不同进制数之间的转换和应用.docx
《不同进制数之间的转换和应用.docx》由会员分享,可在线阅读,更多相关《不同进制数之间的转换和应用.docx(17页珍藏版)》请在冰豆网上搜索。
不同进制数之间的转换和应用
不同进制数之间的转换和应用
例1(ZOJ-1383):
给出一个正整数,将它用2进制表示,如果位置上的数是1,则把它的1所在的位置打印出来.规定最低位标志为0.如13,位置上为1的有0,2,3.
输入:
输入的第一行包含一个正整数d,表示要测试的数据有多少种.
1<=d<=10;接着输入d行,每行有一个正整数n,1<=n<=10^6.
输出:
输出应有d行,每行对应一组测试的结果.每一行的数列成递增排列.
分析:
只要把n转换成2进制就可以了。
源代码:
#include
#include
#include
intmain()
{
intn,i,j;
boolbo;
scanf("%d",&n);
long*p=(long*)malloc(sizeof(long)*n);
for(i=0;iscanf("%ld",&p[i]);
for(i=0;i{
bo=true;
j=0;
while(p[i]!
=0)
{
if(p[i]%2==1)
if(bo)
{
printf("%d",j);
bo=false;
}
else
printf("%d",j);
j++;
p[i]=p[i]/2;
}
printf("\n");
}
system("pause");
return0;
}
例2(ZOJ-1712):
当一个数用10进制表示时,第kth位代表10^k的倍数.
81307(10)=8*10^4+1*10^3+3*10^2+0*10^1+7*10^0
=80000+1000+300+0+7
=81307.
当一个数用2进制表示时,第kth位代表2^k的倍数.
10011
(2)=1*2^4+0*2^3+0*2^2+1*2^1+1*2^0
=16+0+0+2+1
=19.
现在出现一种特殊的进制,叫skew2进制.第kth位代表2^(k+1)-1的倍数.
10120(skew)=1*(2^5-1)+0*(2^4-1)+1*(2^3-1)+2*(2^2-1)+0*(2^1-1)
=31+0+7+6+0
=44.
输入:
有多种测试,每行有一个整数n,如果n=0停止测试.n是用skew进制表示的整数.
输出:
对每一个数,输出它的10进制表示.
源代码:
#include
#include
intmain()
{
longintsum;
inti,j,k;
charp[100];
scanf("%s",p);
while(p[0]!
='0')
{
sum=0;
j=strlen(p);
k=1;
for(i=j-1;i>=0;i--)
{
k=k*2;
sum=sum+(p[i]-'0')*(k-1);
}
printf("%ld\n",sum);
scanf("%s",p);
}
return0;
}
例3(ZOJ-2371):
考虑所有由非负的3的次方组成的集合.
S={1,3,9,27,81,...}
考虑由S的子集组成的序列(按子集里元素的总和递增排列).问题是找出在这个序列里第n-th个位置上的子集,并将它按元素递增的方向排列.
输入:
每行包含一个数n,并且n不超过19位.当n=0时,停止测试.
输出:
对每个n,输出第n-th个子集.输出格式如下.
输入:
1
14
783
1125900981634049
0
输出:
{}
{3,9}
{3,9,27,6561,19683}
{59049,3486784401,205891132094649,
717897987691852588770249}
分析:
观察这个序列的前几项{},{1},{3},{1,3},{9},
{1,9},{3,9},{1,3,9}。
对于{1,3,9,27,81,...},1为第一位,3为第二位,9位第三位。
如果把{}对应0(什么都没有);{1}对应1;{3}对应10;{1,3}对应11;{9}对应100;{1,9}对应101;{3,9}对应110;{1,3,9}对应111。
发现规律这个序列的每一项对应一个唯一的2进制码,且从左直右,连续递增。
而2进制0,1,10,11,100,101,110,111。
。
。
。
。
刚好对应10进制中的0,1,2,3,4,5,6,7,8。
。
。
。
。
因此求第n-th个子集可以先把n转化成2进制的格式。
且定义从右直左为第一位,第二位,第三位。
。
。
。
。
。
。
在n的2进制格式里,那一位是1,就表示包含集合S
{1,3,9,27,81,...}中的第几个元素。
源代码:
#include
#include
#include
voidf(char*a,char*c)
{
inti,j,ca,*s;
ca=strlen(a);
s=(int*)malloc(sizeof(int)*(ca+1));
for(i=0;is[i]=0;
for(i=1;i<=ca;i++)
s[i]=(a[i-1]-'0')*3;
for(i=ca;i>=0;i--)
if(s[i]>=10)
{
s[i-1]+=s[i]/10;
s[i]%=10;
}
i=0;
while(s[i]==0)
i++;
for(j=0;ic[j]=s[i]+'0';
c[j]='\0';
printf("%s\n",c);
free(s);
}
intmain()
{
longlongn;
inti,j;
boolsign;
chars[64][40],p[64];
s[0][0]='1';
s[0][1]='\0';
for(i=1;i<64;i++)
f(s[i-1],s[i]);
scanf("%lld",&n);
while(n!
=0)
{
if(n==1)
printf("{}\n");
else
{
i=0;
n--;
while(n!
=0)
{
p[i]=n%2+'0';
n/=2;
i++;
}
p[i]='\0';
sign=true;
printf("{");
for(j=0;j
if(p[j]=='1')
{
if(sign)
{
printf("%s",s[j]);
sign=false;
}
else
printf(",%s",s[j]);
}
printf("}\n");
}
scanf("%lld",&n);
}
return0;
}
例4(ZOJ-1272):
一位喜欢玩字谜游戏人决定把从1-20个字母间的单词跟唯一的整数建立一种映射。
映射规则很简单,这些单词先按长度排列,同长度的再按字典序排列。
部分映射如下:
a1
b2
...
z26
aa27
ab28
...
snowfall157,118,051,752
...
你的任务是编写一个程序,能在这唯一的单词对应的数和这个单词间进行转换。
输入:
输入的是一系列的单词和数,每一行从第一列开始输入。
如果一行输入的是数,那它只包含0-9。
如果一行输入的是单词,那它只包含a-z。
如果一行输入是‘*‘,测试停止。
输出:
每一行输出一个单词和它对应的数。
每一行单词先从第一列开始输出。
接着在第23列开始输出对应的数。
这个数从右直左每3个作为一个单元,以‘,’隔开。
输入:
29697684282993
transcendental
28011622636823854456520
computationally
zzzzzzzzzzzzzzzzzzzz
*
输出:
elementary29,697,684,282,993
transcendental51,346,529,199,396,181,750
prestidigitation28,011,622,636,823,854,456,520
computationally232,049,592,627,851,629,097
zzzzzzzzzzzzzzzzzzzz20,725,274,851,017,785,518,433,805,270
分析:
观察映射关系,想能不能用26进制数,将这些单词有序的表示出来。
可这里没有字母对应0。
不能直接应用26进制。
但我们可以把它看成一个特殊的26进制,从1-26。
先考虑从单词转化成数,假如
word=x1x2x3…xn.(x1,x2,…,xn都为字母)
number=0;
for(i=1;i<=n;i++)//这里先不考虑高精度问题。
{
number=number*26;
number+=xi-‘a’+1;
}
把数转换成单词
while(number!
=0)//没考虑高精度问题
{
number--;
xi=number%26+’a’;
number/=26;
i++;
}
这时得到的word与要求的单词正好反序。
源代码:
#include
#include
#include
voidmultiply(char*a,char*b,char*c)
{
inti,j,ca,cb,*s;
ca=strlen(a);
cb=strlen(b);
s=(int*)malloc(sizeof(int)*(ca+cb));
for(i=0;is[i]=0;
for(i=0;ifor(j=0;js[i+j+1]+=(a[i]-'0')*(b[j]-'0');
for(i=ca+cb-1;i>=0;i--)
if(s[i]>=10)
{
s[i-1]+=s[i]/10;
s[i]%=10;
}
i=0;
while(s[i]==0)
i++;
for(j=0;ic[j]=s[i]+'0';
c[j]='\0';
free(s);
}
intdividor(char*a,intb,char*c)
{
inti,j,temp=0,n;
char*s;
n=strlen(a);
s=(char*)malloc(sizeof(char)*(n+1));
for(i=0;a[i]!
=0;i++)
{
temp=temp*10+a[i]-'0';
s[i]=temp/b+'0';
temp%=b;
}
s[i]='\0';
for(i=0;s[i]=='0'&&s[i]!
='\0';i++);
if(s[i]=='\0')
{
c[0]='0';
c[1]='\0';
}
else
{
for(j=0;s[i]!
='\0';i++,j++)
c[j]=s[i];
c[j]='\0';
}
free(s);
returntemp;
}
voidadd(char*a,char*b,char*c)
{
inti,j,k,max,min,n,temp;
char*s,*pmax,*pmin;
max=strlen(a);
min=strlen(b);
if(max{
temp=max;
max=min;
min=temp;
pmax=b;
pmin=a;
}
else
{
pmax=a;
pmin=b;
}
s=(char*)malloc(sizeof(char)*(max+1));
s[0]='0';
for(i=min-1,j=max-1,k=max;i>=0;i--,j--,k--)
s[k]=pmin[i]-'0'+pmax[j];
for(;j>=0;j--,k--)
s[k]=pmax[j];
for(i=max;i>=0;i--)
if(s[i]>'9')
{
s[i]-=10;
s[i-1]++;
}
if(s[0]=='0')
{
for(i=0;i<=max;i++)
c[i-1]=s[i];
c[i-1]='\0';
}
else
{
for(i=0;i<=max;i++)
c[i]=s[i];
c[i]='\0';
}
free(s);
}
voidchange(chars[])
{
inti,j;
charc;
j=strlen(s);
for(i=0,j=j-1;i{
c=s[i];
s[i]=s[j];
s[j]=c;
}
}
voidsubtract(char*a,char*b,char*c)
{
inti,j,ca,cb;
ca=strlen(a);
cb=strlen(b);
if(ca>cb||(ca==cb&&strcmp(a,b)>=0))
{
for(i=ca-1,j=cb-1;j>=0;i--,j--)
a[i]-=(b[j]-'0');
for(i=ca-1;i>=0;i--)
if(a[i]<'0')
{
a[i]+=10;
a[i-1]--;
}
i=0;
while(a[i]=='0')
i++;
if(a[i]=='\0')
{
c[0]='0';
c[1]='\0';
}
else
{
for(j=0;a[i]!
='\0';i++,j++)
c[j]=a[i];
c[j]='\0';
}
}
else
{
for(i=ca-1,j=cb-1;i>=0;i--,j--)
b[j]-=(a[i]-'0');
for(j=cb-1;j>=0;j--)
if(b[j]<'0')
{
b[j]+=10;
b[j-1]--;
}
j=0;
while(b[j]=='0')
j++;
i=1;
c[0]='-';
for(;b[j]!
='\0';i++,j++)
c[i]=b[j];
c[i]='\0';
}
}
intmain()
{
inti,j,n;
chars[40],sa[40],sb[40],temp[4];
scanf("%s",s);
while(s[0]!
='*')
{
if(s[0]>='0'&&s[0]<='9')
{
i=0;
strcpy(sa,s);
while(s[0]!
='0')
{
subtract(s,"1",s);
sb[i++]=dividor(s,26,s)+'a';
}
sb[i]='\0';
change(sb);
}
else
{
strcpy(sb,s);
n=strlen(s);
i=s[0]-'a'+1;
if(i<=9)
{
sa[0]=i+'0';
sa[1]='\0';
}
else
{
sa[0]=i/10+'0';
sa[1]=i%10+'0';
sa[2]='\0';
}
for(i=1;i{
multiply(sa,"26",sa);
j=s[i]-'a'+1;
if(j<=9)
{
temp[0]=j+'0';
temp[1]='\0';
}
else
{
temp[0]=j/10+'0';
temp[1]=j%10+'0';
temp[2]='\0';
}
add(sa,temp,sa);
}
}
printf("%-22s",sb);
n=strlen(sa);
switch(n%3)
{
case0:
for(i=0;i{
printf("%c",sa[i]);
if(i%3==2&&i!
=n-1)
printf(",");
}
break;
case1:
for(i=0;i{
printf("%c",sa[i]);
if(i%3==0&&i!
=n-1)
printf(",");
}
break;
case2:
for(i=0;i{
printf("%c",sa[i]);
if(i%3==1&&i!
=n-1)
printf(",");
}
}
printf("\n");
scanf("%s",s);
}
return0;
}