问题描述
小蓝对一个数的数位之和很感兴趣, 今天他要按照数位之和给数排序。当 两个数各个数位之和不同时, 将数位和较小的排在前面, 当数位之和相等时, 将数值小的排在前面。
例如, 2022 排在 409 前面, 因为 2022 的数位之和是 6, 小于 409 的数位 之和 13 。
又如, 6 排在 2022 前面, 因为它们的数位之和相同, 而 6 小于 2022 。
给定正整数 n,m, 请问对 1 到 n 采用这种方法排序时, 排在第 m 个的元 素是多少?
输入格式
输入第一行包含一个正整数 n 。
第二行包含一个正整数 m 。
输出格式
输出一行包含一个整数, 表示答案。
样例输入
13
5
本题本质上是对sort函数深一步的学习
样例输出
3
样例说明
1 到 13 的排序为: 1,10,2,11,3,12,4,13,5,6,7,8,91,10,2,11,3,12,4,13,5,6,7,8,9 。第 5 个数为 3 。
评测用例规模与约定
对于 30% 的评测用例, 1≤m≤n≤300 。
对于 50% 的评测用例, 1≤m≤n≤1000 。
对于所有评测用例, 1≤m≤n≤10^6 。
运行限制
- 最大运行时间:3s
- 最大运行内存: 512M
解法一:利用两个数组,一个存储数位之和,另一个存储需要排序的数
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int b[N],a[N];//b[N]:存储数位之和;a[i]:排序之前按顺序存储1~n之间的数,排序之后存储此题的解;其实也可以用结构体来做这道题目
bool cmp(int x,int y)
{
if(b[x]==b[y]) return x<y;//如果x和y对应的数位之和相等,当比较x与y谁在前谁在后时,则cmp函数返回:x在前面,y在后面
if(b[x]!=b[y]) return b[x]<b[y];//如果x和y对应的数位之和不相等,当比较x与y谁在前谁在后时,
//则cmp函数返回:根据x的数位之和的大小与 y的数位之和的大小比较,将小的数位之和对应的原数据放在前面,大的放在后面
// return b[x]<b[y]||b[x]==b[y]&&x<y;也可以把上面的注释掉换成这个,先执行||左边的,再执行右边的,上下代码是等价的
}
int main()
{
int m,c,n;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int num=i;
while(num){ //将每个数计算他的数位之和并存储在b当中。
b[i]+=num%10;
num/=10;
}
a[i]=i;
}
sort(a+1,a+1+n,cmp);//这里的sort函数并不是简单的根据值的大小进行排序,而是对它的cmp函数定义比较规则,更多用法 csdn搜 sort函数的cmp用法
cout<<a[m]<<endl;
// 请在此输入您的代码
return 0;
}
解法二 (结构体解法):原理相同
#include <iostream>
#include <algorithm>
using namespace std;
struct sw
{
int m;
int ssum;
}a[1000100];
bool px(sw a, sw b)
{
if(a.ssum == b.ssum) return a.m < b.m;
return a.ssum < b.ssum;
}
int main()
{
// 请在此输入您的代码
int n, x;
cin >> n >> x;
for(int i = 1; i <= n; i ++)
{
//cin >> a[i].m;
a[i].m = i;
int t = a[i].m;
a[i].ssum = 0;
while(t)
{
int ge = t % 10;
t /= 10;
a[i].ssum += ge;
}
}
sort(a+1,a+n+1,px);
cout << a[x].m;
return 0;
}