为了更好的阅读体检,可以查看我的算法学习博客华东师范大学保研机试-2022-整数排序
题目内容
输入若干个int类型整数,将整数按照位数由大到小排序,如果位数相同,则按照整数本身从小到大排序。
例如,
输入:10 -3 1 23 89 100 9 -123
输出:-123 100 10 23 89 -3 1 9
输入的整数个数最多不超过个。
输入格式
在一行中输入若干个整数,整数之间用一个空格分隔。
输出格式
在一行中输出排序好的整数,整数之间用一个空格分隔。
样例
input1
10 -3 1 23 89 100 9 -123
ouput1
-123 100 10 23 89 -3 1 9
input2
1 -2 12
ouput2
12 -2 1
题解
思路
1.这是一类经典的条件排序问题,它就是排序问题的小变形。具体到语法上就是一个结构体排序。
2.由于题目说明了数组长度。所以就不要自己写冒泡排序等比较慢的排序了。在C++可直接使用STL中的排序函数函数:sort()。而且就算是你会手写快排,也不建议这么做。因为一方面是比赛的时候浪费时间,另一方面是STL中的sort加了很多优化,它比你手写的快排还会更快。
使用方法
// 1.需要的头文件 #include <algorithm> // 如果不想记这么多繁杂的头文件,你永远可以相信<万能头文件>,它包罗万象了,至少各种比赛,机试是够用的。 #include <bits/stdc++.h> // 2.sort的使用方法 sort (起始地址,结束地址的下一位,自定义排序函数的函数名) // 起始/结束地址:传入对应的指针,一定要注意是结束的地址的下一位! // 自定义排序函数:告诉sort函数将如何比较两个数,谁放在前面,谁放在后面。不传参时默认是升序排序。 // 3.具体案例1:给定一个整数数组a,我们希望对其下标为[l,r]的区域<升序>排序 sort(a + l , a + r + 1)
Copy
回到这道题,它的关键其实就是构造自定义排序函数。我们来展开讲一讲这一点。
//具体案例2:给定一个整数数组a,我们希望对其下标为[l,r]的区域<降序>排序 //这时我们可以自己构造一个自定义排序的函数cmp(函数名随意命名),然后将函数名填入第三个参数(这个在语法上叫做函数传参,本质是传递函数指针) sort(a + l , a + r + 1 , cmp); // 返回值为bool型,传入两个参数a , b // 这个函数的作用是告诉sort函数将如何比较两个数。当返回true的时候将a放在b之前,返回false的时候将b放在a之前 bool cmp (const int& a , const int& b){ //if (a > b) return true; //else return false; //利用语法特性,直接返回逻辑表达式 return a > b; } // 更多解释:1.利用引用变量是为了加快速度,减少拷贝时间。2.使用const修饰是为了防止我们误改内容。 //所以你不加这两个,直接写int a , int b 也不会有问题,只是不规范罢了。
Copy
所以这题的关键就是构造自定义排序函数cmp。代码如下:
#include <bits/stdc++.h> using namespace std; struct Val{ int dig; // 数位长度 int val; // 数字 }; Val a[1000006]; // 获得数位长度 int getDig (int val){ val = abs(val); int ans = 0; while (val){ ans ++; val /= 10; } return ans; } int cmp (const Val & a , const Val& b){ if (a.dig != b.dig) return a.dig > b.dig; return a.val < b.val; } int main() { int x , n = 0; while (cin >> x) { a[++n].val = x; a[n].dig = getDig(a[n].val); } sort(a + 1 , a + n + 1 , cmp); for (int i = 1 ; i <= n ; i++){ cout << a[i].val; if (i == n) cout << endl; else cout << " "; } return 0; }
Copy
总结
考察知识点:条件排序问题
评价:这是机试第一题,难度比较小。如果平时有在刷题应该是能秒掉的。