不同进制数之间的转换和应用.docx

上传人:b****5 文档编号:5128127 上传时间:2022-12-13 格式:DOCX 页数:17 大小:18.93KB
下载 相关 举报
不同进制数之间的转换和应用.docx_第1页
第1页 / 共17页
不同进制数之间的转换和应用.docx_第2页
第2页 / 共17页
不同进制数之间的转换和应用.docx_第3页
第3页 / 共17页
不同进制数之间的转换和应用.docx_第4页
第4页 / 共17页
不同进制数之间的转换和应用.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

不同进制数之间的转换和应用.docx

《不同进制数之间的转换和应用.docx》由会员分享,可在线阅读,更多相关《不同进制数之间的转换和应用.docx(17页珍藏版)》请在冰豆网上搜索。

不同进制数之间的转换和应用.docx

不同进制数之间的转换和应用

不同进制数之间的转换和应用

例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;i

scanf("%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;i

s[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;i

c[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;i

s[i]=0;

for(i=0;i

for(j=0;j

s[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;i

c[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;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 文学研究

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1