问题(组合数学)
问题描述
小蓝对一个数的数位之和很感兴趣, 今天他要按照数位之和给数排序。当 两个数各个数位之和不同时, 将数位和较小的排在前面, 当数位之和相等时, 将数值小的排在前面。
例如, 2022 排在 409 前面, 因为 2022 的数位之和是 6, 小于 409 的数位 之和 13 。
又如, 6 排在 2022 前面, 因为它们的数位之和相同, 而 6 小于 2022 。
给定正整数 n,m, 请问对 1 到 n 采用这种方法排序时, 排在第 m个的元 素是多少?
输入格式
输入第一行包含一个正整数 n。
第二行包含一个正整数 m。
输出格式
输出一行包含一个整数, 表示答案。
样例输入
13
5
样例输出
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%30% 的评测用例, 1≤m≤n≤3001≤m≤n≤300 。对于
50%50% 的评测用例, 1≤m≤n≤10001≤m≤n≤1000 。
对于所有评测用例, 1≤m≤n≤1061≤m≤n≤106 。
运行限制
- 最大运行时间:3s
- 最大运行内存: 512M
解题思路:
1、先对数位之和进行排序
2、若数位之和相同,再对数进行排序
详细内容 :
1.定义两个数组sum[]:数位之和
a[]:数字本身
2.求1到n每个数字的数位和
(1)i为1-9:sum[i]=本身
(2)a[i]=i:在cmp中的x,y
for(int i=1;i<=n;i++)
{
int num=i;
while(num)
{
sum[i]+=num%10;
num/=10;
}
a[i]=i;
}
3.定义排序规则,进行排序
(1)当两个数各个数位之和不同时, 将数位和较小的排在前面;
(2)当数位之和相等时, 将数值小的排在前面
返回true,排在 x
应该排在 y
前面。
否则,y
应该排在 x
前面。
bool cmp(int x,int y)
{
if(sum[x]<sum[y])
{
return true;
}
else if(sum[x]==sum[y]&&x<y)
{
return true;
}
else
{
return false;
}
}
总代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int maxn=1e6+100;//1000100;
LL n,m;
LL sum[maxn];
LL a[maxn];
bool cmp(int x,int y)
{
if(sum[x]<sum[y])
{
return true;
}
else if(sum[x]==sum[y]&&x<y)
{
return true;
}
else
{
return false;
}
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int num=i;
while(num)
{
sum[i]+=num%10;
num/=10;
}
a[i]=i;
}
sort(a+1,a+1+n,cmp);
cout<<a[m]<<endl;
return 0;
}
要点:
(1)sum[],a[]数组需要有长度,可以直接写数字
LL sum[100000000] ;
LL a[100000000] ;
也可以定义常量,注意前面必须加const
const int maxn=1e6+100;
(2)
-
sort
是 C++ STL 中的一个排序函数,位于<algorithm>
头文件中。 -
a+1
和a+1+n
是排序的范围:-
a+1
表示从数组a
的第 2 个元素开始(因为数组下标从 0 开始,a+1
跳过了第 1 个元素)。 -
a+1+n
表示排序的结束位置是第n+1
个元素(即对n
个元素进行排序)。
-
-
cmp
是一个可选的比较函数,用于定义排序的规则。如果省略cmp
,则默认按升序排序
sort(a+1,a+1+n,cmp);