3505Yet Another Set of Numbers (数学模拟题)

来源:互联网 发布:php成绩管理系统代码 编辑:程序博客网 时间:2024/04/29 22:02
Time Limit: 2 Seconds      Memory Limit: 65536 KB

You are given yet another set of numbers. The numbers in this set obey these rules:

  1. Each number will start with a non-zero digit.
  2. Each number contains at most N digits and only 0, 1, 2 and 3 are available.
  3. All the adjacent digits won't be the same (e.g. 301 is legal while 300 is illegal).
  4. The comparison is the same as strings (e.g. 1 < 123 < 20 < 21 < 3).

Given a number B belonging to this set, you have to find out the number A such that there are exactly K-1 numbers larger than A and smaller than B in this set.

Input

Input contains multiple test cases.

The first line of each test case contains two integers 0 < N < 20 and K > 0. The second line contains only a number B. It's guaranteed that the solution exists

Output

For each case, output the number A in a single line.

Sample Input

2 535 5012301

Sample Output

131021

Hint

In the first case, there are 12 numbers in the set. And they are sorted in following order:
1 < 10 < 12 < 13 < 2 < 20 < 21 < 23 < 3 < 30 < 31 < 32

//找到每个排列和其的序列号之间的转换规律就可以了,很水的说,比赛的时候写完伪代码,但是机器一直被师哥占着,所以。。。

//每位都有一个权值w[0]=1,w[i]=w[i-1]*3+1;乘3是0 1 2 3中有3个和前一个值不一样,+1是前一位是最后一位的情况也就是没有这位和之后的位数

#include <cstdio>
#include <string.h>
int n,k,a,b;
char A[21],B[21];//存放啊a b串的字符型
int w[21];
int num[21],ans[21];//存放b a 串的整型
int decode (int len)
{
    int ret=len,i;
    ret+=(num[0]-1)*w[n];
    for(i=1 ; i<len ; i++)
    {
         if(num[i]>num[i-1])ret+=(num[i]-1)*w[n-i];
         else ret+=num[i]*w[n-i];
    }
    return ret;
}
int code (int x)
{
    if(x!=0)x=x-1;
    ans[0]=(x/w[n])+1;
    x=x-x/w[n]*w[n];
    int i=0;
    for(i=1; i<n ; i++)
    {
         if(x>0)
         {
             if(x!=0)x--;
             ans[i] = x/w[n-i];
             x-=x/w[n-i]*w[n-i];
             if(ans[i]>=ans[i-1]) ans[i]++;
            
         }
         else ans[i]=-1;
         //printf("a%d=%d/n",i,ans[i]);
    }
    for(int i=0 ; i<n ; i++)
    {
        if(ans[i]>=0)A[i]=char(ans[i]+'0');
        else A[i]='/0';
    }
}
int main ()
{
    w[1]=1;
    for (int i=2 ; i<22 ;i++)
     w[i]=w[i-1]*3+1;
    while (scanf("%d%d",&n,&k)!=EOF)
    {
          memset(A,'/0',sizeof(A));
          memset(B,'/0',sizeof(B));
          scanf("%s",B);
          int len =strlen (B);
          for (int i=0; i<len ; i++)
          {
               num[i]=B[i]-'0';
          }
          b=decode (len);//将B翻译成它对应的序列号
          //printf("%d/n",b);
          code (b-k);//将b-k译成对应的字符串A
          printf("%s/n",A);
    }
    return 0;
}