Description
今天zyb參加一場面試,面試官聽說zyb是ACMer之後立馬拋出了一道算法題給zyb:
有一個序列,是1到n的一種排列,排列的順序是字典序小的在前,那麼第k個數字是什麼?
例如n=15,k=7, 排列順序爲1, 10, 11, 12, 13, 14, 15, 2, 3, 4, 5, 6, 7, 8, 9;那麼第7個數字就是15.
那麼,如果你處在zyb的場景下,你能解決這個問題嗎?
Input
T組樣例(T<=100)
兩個整數n和k(1<=n<=1e6,1<=k<=n),n和k代表的含義如上文
Output輸出1-n之中字典序第k小的數字
Sample Input
1
15 7
Sample Output
15
方法一: (這個方法是在網上百度到的,太巧妙,一般想不出來)
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
const int MAX=1e9+7;
const int MM=192600817;
deque <ll> dq;
int main()
{
ll T,n,m,i,j,k;
cin>>T;
while(T--)
{
cin>>n>>k;
ll x=1;
while(k>1)
{
if(x*10<=n)
{
x=x*10;
k--;
}
else
{
if(x+1<=n)
{
while(x%10==9)
x=x/10;
x++;
k--;
}
else
{
x=x/10;
while(x%10==9)
x=x/10;
x++;
k--;
}
}
}
cout<<x<<endl;
}
return 0;
}
方法二:直接暴力打表,按字符串排序之後,每次找的時候看與n的關係,如果比n大直接跳過,直到第k個數爲止。
AC代碼:
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
const int MAX=1e6;
const int MM=192600817;
struct A
{
ll k;
char s[8];
}a[MAX+1];
bool cmp(struct A p,struct A q)
{
return strcmp(p.s,q.s)<0;
}
int main()
{
ll T,n,k,i,j;
for(i=1;i<=MAX;i++)
{
a[i].k=i;
ll t=i,e=0,m;
while(t)
{
a[i].s[e]=(t%10)+'0';
t/=10;
e++;
}
for(j=0;j<e/2;j++)
{
char tt;
tt=a[i].s[j];
a[i].s[j]=a[i].s[e-j-1];
a[i].s[e-j-1]=tt;
}
}
sort(a+1,a+MAX+1,cmp);
//cout<<a[1000].s<<endl;
cin>>T;
while(T--)
{
cin>>n>>k;
i=1;
for(i=1;i<=MAX;i++)
{
if(a[i].k>n)
continue;
else
k--;
if(k==0)
break;
}
cout<<a[i].k<<endl;
}
return 0;
}