相邻数字的基数不等比:skew数

2973:Skew数
 
描述
在 skew binary表示中, 第 k 位的值xk表示xk*(2k+1-1)。 每个位上的可能数字是0 或 1,最后面一个非零位可以是2, 例如, 10120(skew) = 1*(25-1) + 0*(24-1) + 1*(23-1) + 2*(22-1) + 0*(21-1) = 31 + 0 + 7 + 6 + 0 = 44. 前十个skew数是 0、1、2、10、11、12、20、100、101、以及102。
输入
输入包含一行或多行,每行包含一个整数n。 如果 n = 0 表示输入结束,否则n是一个skew 数
输出
对于每一个输入,输出它的十进制表示。转换成十进制后, n 不超过 2^31-1 = 2147483647
样例输入
10120
200000000000000000000000000000
10
1000000000000000000000000000000
11
100
11111000001110000101101102000
0
样例输出
44
2147483646
3
2147483647
4
7
1041110737

我最开始的解法:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
int skewToTen(char *a)
{
    int len=strlen(a);
    int ret=0;
    for(int i=len-1;i>=0;i--)
    {
        int x=a[i]-'0';
        ret+=x*( pow((double)2,len-1-i+1)-1);
    }
    return ret;
}
        
int main()
{
    char a[40];
    while(scanf("%s",a)&&atoi(a)!=0)
    {
        int ret=skewToTen(a);
        printf("%d\n",ret);
 
    }
}

效率很低,没有考虑数组应该开多大?

 如何确定数组应该开多大?可以这样分析,如最大开一个长度为k的skew数,最后一个数组的基数为(2^k-1);

由于转成10进制后,n不超过 2^31-1 ;因此skew数最大长度不超过31.数组开32就可以了。

 用一个整形数组base[31],依次存储skew数最末位,倒数第二位,。。。。。。。。。。第31位的基数值,使用

这个数组,把每个skew数换成对应的十进制数。

base[0]=1

base[k]=2^(k+1)-1=2*(2^k)+1=2*base[k-1]+1;

生成递推公式。

判断输入的字符串是否为0用了strcmp函数。

#include<stdio.h>
#include<string.h>
int main()
{
    
    int i,k,base[31],sum;
    char skew[32];
    base[0]=1;
    for(int i=1;i<31;i++) base[i]=2*base[i-1]+1;
    while(1)
    {
        scanf("%s",skew);
        if(strcmp(skew,"0")==0)
            break;
        sum=0;
        k=strlen(skew);
        for(i=0;i<strlen(skew);i++)
        {
            k--;
            sum+=(skew[i]-'0')*base[k];
        }
        printf("%d\n",sum);
    }

}

现在程序的效率就很高了。

 

 

转载请注明出处:http://www.0519diyi.com/article/20230310/680548.html