算法分类:
自定义排序
问题描述
小蓝对一个数的数位之和很感兴趣,今天他要按照数位之和给数排序。
当两个数各个数位之和不同时,将数位和较小的排在前面,当数位之和相等时,将数值小的排在前面。
例如,2022 排在 409 前面,因为 2022 的数位之和是 6,小于 409 的数位之和 13。
又如,6 排在 2022 前面,因为它们的数位之和相同,而 6 小于2022。
给定正整数n,m,请问对 1 到 n 采用这种方法排序时,排在第 m 个的元素是多少?
输入格式
输入第一行包含一个正整数 n。
第二行包含一个正整数 m。
输出格式
输出一行包含一个整数,表示答案。
数据范围
对于 30% 的评测用例,1≤m≤n≤300。
对于50% 的评测用例,1≤m≤n≤1000。
对于所有评测用例,1≤m≤n≤106。
输入样例:
13
5
输出样例:
3
样例解释
1 到 13 的排序为:1,10,2,11,3,12,4,13,5,6,7,8,9。
第 5 个数为 3。
原因分析:
根据题目要求,可知,如果两个数的数位之和不同时,那么数位和越大,排序越靠后;
如果两个数的数位和相同,按照数的原本的大小关系排序。
根据规则,自定义排序规则,可重写cmp函数,定义pair元素,一个为数位和,一个为数值。
实现代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#define x first
#define y second
using namespace std;
const int N = 1e6+10;
int n,m;
typedef pair<int,int> PII;
PII q[N];//x表示数位之和 y表示大小
bool cmp(PII a,PII b){
if(a.x!=b.x) return a.x<b.x;
return a.y<b.y;
}
int main(){
cin >> n >> m;
for(int i=1;i<=n;i++){
q[i].y = i;
int t = i;
while(t){
q[i].x+=t%10;
t/=10;
}
}
sort(q+1,q+1+n,cmp);
cout<<q[m].y<<endl;
return 0;
}