Little Sub and Mr.Potato's Math Problem
Time Limit: 2 Seconds Memory Limit: 65536 KB
Little Sub loves math very much. He enjoys counting numbers.
One day, Mr.Potato gives him an interesting math problem. Please help Little Sub solve this problem.
Let's sort the integers according to alphabetical order. For example, when , the order should be: .
We define as the position of number in the sorted numbers. For example, .
Given and , please find the smallest such that .
Input
There are multiple test cases. The first line of the input contains an integer (), indicating the number of test cases. For each test case:
The first and only line contains two integers and (, ).
Output
For each test case, please output the answer in one line. If there is no such , please output "0" (without quotes).
Sample Input
2
2 4
10000001 100000000
Sample Output
11
1000000088888880
Author: ZHANG, Zhihuan
Source: ZOJ Monthly, January 2019
给你k,m ,k这个数按照字典序排列在第m位 ,问你这个序列最小是多长
按照字典序排列
比如130 1000这组数据
1-1 在前面 有1个
10-13 在前面 有4个
100-129 在前面 有30个 //注意如果到了该数的长度及以上需要-1;
判完该数的长度还是不够 (注意,至少要有30+4+1个数在前面,所以要是m<=35,根本不可能组成序列,直接输出0)
继续
1000-1299 在前面 有300个
还不够 继续
10000-12999 在前面 有3000个
够了
那么这个序列最小长度就应该书是10000+(1000-300-30-4-1-1)-1=10663
一定要排在前面的335个,自己位置保留一个,那么从10000开始要1000-335-1=664个
所以答案是10663
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int pos;
int a[18],b[18];
int flag;
void cal(ll n)
{
while(n)
{
a[++pos]=n%10;
n/=10;
}
for(int i=1;i<=pos;i++)
{
b[i]=a[pos-i+1];
if(i==1)
{
if(b[i]==1)
flag++;
}
else
{
if(b[i]==0)
{
flag++;
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
flag=0;
pos=0;
memset(a,0,sizeof a);
ll num=0;
ll n,m;
scanf("%lld%lld",&n,&m);
m--;
cal(n);
ll p=1,q;
int f=0;
for(int i=1;i<=pos;i++)
{
if(i==1) p=1;
else p*=10;
if(i!=pos)
{
for(int j=1;j<=i;j++)
{
if(j==1) q=b[j];
else q=q*10+b[j];
}
}
else
{
for(int j=1;j<=i;j++)
{
if(j==1) q=b[j];
else q=q*10+b[j];
}
q--;
}
num+=q-p+1;
}
if(num>m) f=1;
if(flag==pos&&(int)m+1==flag)
{
printf("%lld\n",n);
continue;
}
else if(flag==pos&&q<p)
{
printf("0\n");
continue;
}
//cout<<p<<" "<<q<<" "<<num<<" "<<m<<endl;
if(num==m)
{
cout<<n<<endl;
continue;
}
while(1)
{
p=p*10;
q=q*10+9;
if(num+q-p+1<m)
{
num+=q-p+1;
continue;
}
else
{
p=p/10;
q=(q-9)/10;
break;
}
}
//cout<<pos<<" "<<flag<<endl;
p=p*10;
p+=m-num-1;
if(flag!=pos&&!f)
{
printf("%lld\n",p);
}
else
{
printf("0\n");
}
}
return 0;
}