zl程序教程

您现在的位置是:首页 >  其他

当前栏目

数位排序(蓝桥杯sort的cmp函数)

2023-04-18 16:47:53 时间

问题描述

小蓝对一个数的数位之和很感兴趣, 今天他要按照数位之和给数排序。当 两个数各个数位之和不同时, 将数位和较小的排在前面, 当数位之和相等时, 将数值小的排在前面。

例如, 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;
}