题目描述
在蓝桥王国,数字的大小不仅仅取决于它们的数值大小,还取决于它们所形成的“封闭图形的个数。
封闭图形是指数字中完全封闭的空间,例如数字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数从小到大排序,并输出排序后结果。
样例
输入:
3
18 29 6
输出:
6 29 18
样例解释
对于给定的数字序列18,29,6,数字18的封闭图形个数为2,数字29的封闭图形个数为1,数字6的封闭图形个数为1。
按照封闭图形个数从小到大排序后,得到29,6,18。
由于数字29和数字6的封闭图形个数相同,因此需要进一步按照数值大小对它们进行排序,最终得到[6,29,18]。
C++ 代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int hs[N];
int arr[N];
// 当前正在考虑哪家店
int check(int x) {
int res = 0;
while (x) {
if (x % 10 == 4 || x % 10 == 6 || x % 10 == 9 || x % 10 == 0) res += 1;
else if (x % 10 == 8) res += 2;
x /= 10;
}
return res;
}
// 基数排序优化
void radixSort(int arr[], int n) {
vector<int> buckets[18]; // 假设最多有18个封闭图形(数字888888888形成18个封闭图形)
// 根据封闭图形个数将数字放入对应的桶中
for (int i = 1; i <= n; i++) {
int count = check(arr[i]);
buckets[count].push_back(arr[i]);
}
int index = 1;
// 依次从每个桶中取出数字并放回原数组,每个桶内可以再进行排序(这里简单使用sort)
for (int i = 0; i < 18; i++) {
if (!buckets[i].empty()) {
sort(buckets[i].begin(), buckets[i].end());
for (int num : buckets[i]) {
arr[index++] = num;
}
}
}
}
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> arr[i];
}
radixSort(arr, n);
for (int i = 1; i <= n; i++) cout << arr[i] << " ";
return 0;
}