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
本以为要用树进行遍历一定要建立树,但是其实有些时候可以利用dfs的性质对树进行遍历查找,学到了,因为这里要的是字典序所以利用dfs找的第k个数字一定是字典序最小的,因为由于树的结构,所导致dfs找到的第一条满足的线路就是所满足条件的数字;
//利用dfs虚拟模拟十叉树;
#include <iostream>
using namespace std;
int count,ans,flag,k,n;
void dfs(int i)
{
if(flag)//第一次到达满足条件的数后直接结束剩余线路的查找
return ;
count++;
if(count == k){
ans = i;
flag = 1;
return ;//找到满足条件的直接结束这条线路的寻找;
}
if(!i){
for(int j = 1; j <= 9; j++)//第一位数字不能包含0;
dfs(j);
}
else{
for(int j = 0; j <= 9; j++){
int temp = 10 * i + j;//每一层的某个结点时的所到达的数值;
if(temp <= n)//递归边界的判断;
dfs(temp);
else//到达边界后结束此条路线的查找;
return ;
}
}
}
int main()
{
int t;
cin>>t;
while(t--){
cin>>n>>k;
count = -1;
flag = 0;
dfs(0);
cout<<ans<<endl;
}
return 0;
}