- 题目描述:
-
将一个长度最多为30位数字的十进制非负整数转换为二进制数输出。
- 输入:
-
多组数据,每行为一个长度不超过30位的十进制非负整数。(注意是10进制数字的个数可能有30个,而非30bits的整数)
- 输出:
-
每行输出对应的二进制数。
- 样例输入:
-
0 1 3 8
- 样例输出:
-
0 1 11 1000
- 来源:
- 2008年北京大学软件所计算机研究生机试真题
- 1.自己想的解法特别的复杂
-
#include<stdio.h> #include<string.h> //基本思路,先把大整数拆成几个部分,用二进制算最终结果 int DtoB (char b[],char str[],int len){//转十进制到二进制 int tmp=0; int i; if(len==0) { b[0]=0; return 0; } for(i=len-1;i>=0;--i){ tmp*=10; tmp+=(str[i]-‘0‘); } i=0; do{ b[i++]=tmp%2+‘0‘; tmp/=2; }while(tmp!=0); b[i]=0; return i;//返回位数 } int Badd(char b1[],int size1,char b2[],int size2){//二进制加法,最终放在b2,从低位到高位 int i; int c;//进位 int x; if(size1<=size2){ c=0; for(i=0;i<size1;i++){ x=c+b1[i]-‘0‘+b2[i]-‘0‘; b2[i]=x%2+‘0‘; c=((x>=2)?1:0); } for(i=size1;i<size2;i++){ x=c+b2[i]-‘0‘; b2[i]=x%2+‘0‘; c=((x>=2)?1:0); } if(c==1) b2[i++]=‘1‘; b2[i]=0; return i; } else{ c=0; for(i=0;i<size2;i++){ x=c+b1[i]-‘0‘+b2[i]-‘0‘; b2[i]=x%2+‘0‘; c=((x>=2)?1:0); } for(i=size2;i<size1;i++){ x=c+b1[i]-‘0‘; b2[i]=x%2+‘0‘; c=((x>=2)?1:0); } if(c==1) b2[i++]=‘1‘; b2[i]=0; return i; } } int Bmul(char b[],int len){//二进制乘以10 char bmul2[100];//原来的二进制乘二,就是右移一位 int i; for(i=len;i>=0;i--){//包括\0右移 bmul2[i+1]=b[i]; } bmul2[0]=‘0‘;//第0位补0 for(i=len;i>=0;i--){//乘8,右移3位 b[i+3]=b[i]; } b[0]=b[1]=b[2]=‘0‘; int size=Badd(bmul2,len+1,b,len+3);//最终结果在b里面,size返回大小 return size; } int main(){ char str[31];//大整数 while(scanf("%s",str)!=EOF){ int size=strlen(str); char str1[11],str2[11],str3[11],str4[11];//把十进制字符串拆成4段str1->str3 低位到高位 9位9位分割 int i,j,size1=0,size2=0,size3=0,size4=0; for (i=0;i<11;i++){ str1[i]=‘0‘; } for (i=0;i<11;i++){ str2[i]=‘0‘; } for (i=0;i<11;i++){ str3[i]=‘0‘; } for (i=0;i<11;i++){ str4[i]=‘0‘; } for(size1=0,j=size-1;size1<9&&j>=0;++size1,--j){ str1[size1]=str[j]; } str1[size1]=0; for(size2=0;size2<9&&j>=0;++size2,--j){ str2[size2]=str[j]; } str2[size2]=0; for(size3=0;size3<9&&j>=0;++size3,--j){ str3[size3]=str[j]; } str3[size3]=0; for(size4=0;size4<9&&j>=0;++size4,--j){ str4[size4]=str[j]; } str4[size4]=0; char b1[150],b2[150],b3[150],b4[150];//二进制形式的各段,0位放最低位二进制—>高 int b1_size=DtoB(b1,str1,size1); int b2_size=DtoB(b2,str2,size2); int b3_size=DtoB(b3,str3,size3); int b4_size=DtoB(b4,str4,size4); //int sizea=Badd(b2,b2_size,b1,b1_size);//以上都正确 //int sizea=Bmul(b2,b2_size);// if(b2_size!=0){ for(i=0;i<9;i++){ b2_size=Bmul(b2,b2_size); } b1_size=Badd(b2,b2_size,b1,b1_size); } if(b3_size!=0){ for(i=0;i<18;i++){ b3_size=Bmul(b3,b3_size); } b1_size=Badd(b3,b3_size,b1,b1_size); } if(b4_size!=0){ for(i=0;i<27;i++){ b4_size=Bmul(b4,b4_size); } b1_size=Badd(b4,b4_size,b1,b1_size); } for(i=b1_size-1;i>=0;--i){ printf("%c",b1[i]); } printf("\n"); } return 0; }
2.在网上看到大整数十进制转六进制的解法(来源:十进制大整数转换成十六进制数)
Description
将十进制数转换成十六进制数。
Input
包括多组测试数据。输入一个不超过100位正整数,无前导零。
输入以0结束。
Output
输出其十六进制表示(不打印前导零,A~F字母大写)。
Sample
Input12 20 12345678901234567890 0
Sample Output
C 14 AB54A98CEB1F0AD2 原理:16的倍数乘以625一定能被10000整除,那么一个整数乘以625所得数的最后4位除以625所得值等价于这个整数对16取余。
#include<stdio.h> #include<string.h> void main() { int i,j,a[110],b[110],t; char s[105]; while(gets(s),strcmp(s,"0")){ strrev(s); for(i=0;i<110;i++)a[i]=b[i]=0; for(i=0;s[i];i++)a[i]=s[i]-48;//将字符转化为数字 for(t=1;t<100;t++){ for(i=0;i<110;i++)a[i]*=625; for(i=0;i<110;i++){ if(a[i]>9){ a[i+1]+=a[i]/10; a[i]%=10; } } b[t]=(a[0]+a[1]*10+a[2]*100+a[3]*1000)/625;//求余数 for(i=0;i<105;i++)a[i]=a[i+4];//去掉余数 } for(;!b[t]&&t>1;t--);//去掉前导零 for(;t;t--)printf("%X",b[t]); puts(""); } }
3.用相似的原理
时间: 2024-10-08 23:02:18