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 ",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 ",sum); } }
现在程序的效率就很高了。