时间限制: 5s 内存限制: 512MB 提交: 1486 解决: 508
题目描述
在蓝桥王国,数字的大小不仅仅取决于它们的数值大小,还取决于它们所形成的“封闭图形”的个数。
封闭图形是指数字中完全封闭的空间,例如数字 1、2、3、5、7 都没有形成封闭图形,而数字 0、4、6、9 分别形成了 1 个封闭图形,数字 8 则形成了 2个封闭图形。值得注意的是,封闭图形的个数是可以累加的。例如,对于数字68,由于 6 形成了 1 个封闭图形,而 8 形成了 2 个,所以 68 形成的封闭图形的个数总共为 3。
在比较两个数的大小时,如果它们的封闭图形个数不同,那么封闭图形个数较多的数更大。例如,数字 41 和数字 18,它们对应的封闭图形的个数分别为 1 和 2,因此数字 41 小于数组 18。如果两个数的封闭图形个数相同,那么数值较大的数更大。例如,数字 14 和数字 41,它们的封闭图形的个数都是 1,但 14 < 41,所以数字 14 小于数字 41。如果两个数字的封闭图形个数和数值都相同,那么这两个数字被认为是相等的。
小蓝对蓝桥王国的数字大小规则十分感兴趣。现在,他将给定你 n 个数a1, a2, . . . , an,请你按照蓝桥王国的数字大小规则,将这 n 数从小到大排序,并输出排序后结果。
输入格式
输入的第一行包含一个整数 n ,表示给定的数字个数。
第二行包含 n 个整数 a1, a2, . . . , an ,相邻整数之间使用一个空格分隔,表示待排序的数字。
输出格式
输出一行包含 n 个整数,相邻整数之间使用一个空格分隔,表示按照蓝桥王国的数字大小规则从小到大排序后的结果。
样例输入
3 18 29 6
样例输出
6 29 18
提示
【样例说明】
对于给定的数字序列 [18, 29, 6],数字 18 的封闭图形个数为 2,数字 29 的封闭图形个数为 1,数字 6 的封闭图形个数为 1。按照封闭图形个数从小到大排序后,得到 [29, 6, 18]。由于数字 29 和数字 6 的封闭图形个数相同,因此需要进一步按照数值大小对它们进行排序,最终得到 [6, 29, 18]。
【评测用例规模与约定】
对于 50% 的评测用例,1 ≤ n ≤ 2 × 103,1 ≤ ai ≤ 105。对于所有评测用例,1 ≤ n ≤ 2 × 105,1 ≤ ai ≤ 109。
解题思路
-
封闭图形个数计算:
- 首先,我们需要计算每个数字中封闭图形的个数。可以通过预先定义一个字典来存储每个数字的封闭图形个数。
- 例如:
0
有1个封闭图形,8
有2个封闭图形,等等。
-
排序规则:
- 首先按照封闭图形的个数进行排序。
- 如果封闭图形个数相同,则按照数值大小进行排序。
-
实现步骤:
- 读取输入的数字。
- 计算每个数字的封闭图形个数。
- 使用自定义排序规则对数字进行排序。
- 输出排序后的结果。
代码实现
以下是实现上述思路的代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
// 预定义每个数字的封闭图形个数
std::unordered_map<char, int> closed_shapes = {
{'0', 1}, {'1', 0}, {'2', 0}, {'3', 0}, {'4', 1},
{'5', 0}, {'6', 1}, {'7', 0}, {'8', 2}, {'9', 1}
};
// 计算一个数字的封闭图形个数
int count_closed_shapes(int num) {
std::string num_str = std::to_string(num);
int count = 0;
for (char c : num_str) {
count += closed_shapes[c];
}
return count;
}
// 自定义排序规则
bool compare(int a, int b) {
int count_a = count_closed_shapes(a);
int count_b = count_closed_shapes(b);
if (count_a == count_b) {
return a < b;
}
return count_a < count_b;
}
int main() {
int n;
std::cin >> n;
std::vector<int> numbers(n);
for (int i = 0; i < n; ++i) {
std::cin >> numbers[i];
}
// 按照自定义规则排序
std::sort(numbers.begin(), numbers.end(), compare);
// 输出排序结果
for (int i = 0; i < n; ++i) {
if (i > 0) std::cout << " ";
std::cout << numbers[i];
}
std::cout << std::endl;
return 0;
}