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

本文介绍了一个关于数字排列的问题,探讨了如何找到特定条件下的数字序列。通过对数字进行编码和解码,实现从数字到序列号及反之的转换,进而解决寻找特定数量级之间的数值问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 5
3
5 50
12301
Sample Output
13
1021
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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值