EOJ 3031 二进制倒置

题目描述

给定一个整数 n(0≤n≤10100)、将 n 的 334 位二进制表示形式(不包括开头可能的值为 0 的位,n=0 表示为 1 位 0)前后倒置,输出倒置后的二进制数对应的整数。

例如:n=10,其二进制表示为 (330 个 0)1010,倒置后为 0101,对应输出就是 5。

Input

第 1 行:一个整数 T (1T10) 为问题数。

接下来共 T 行整数,对应每个问题有 1 行,表示 n。

Output

对于每个问题,输出一行问题的编号(0 开始编号,格式:case #0: 等)。

然后对应每个问题在一行中输出结果。

 


 

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define END 10
 4 void init(int *n)
 5 {
 6     char c;int i=0;
 7     while((c=getchar())!='\n')
 8     {
 9         n[i]=c-'0';
10         i++;
11     }
12     n[i]=END;
13 }//用getchar()将大整数逐位读入数组,以换行符为结束标志
14 void multiout(int* out)//将数组表示的整数*2
15 {
16     int *p=out,carry,plus=0;
17     while(1)
18     {
19         if(*p==-1)//乘法结束
20         {
21             if(p-out==0)
22             {
23                 *p=0;
24                 return;
25             }
26             else if(plus==1)
27                     *p=plus;
28             return;
29         }
30         carry=*p*2+plus;  原位置*2+进位
31         *p=carry%10;    
32         plus=carry/10;
33         p++;
34     }
35 
36 }
37 int addout(int* out,int get)
38 {
39     int* p=out;
40     if(get==0) return;
41 
42     else
43     {
44 
45         *p=*p+1;
46         while(*p==10)
47         {
48             *p=0;
49             (*(++p))++;
50         }
51     }//46-51行其实不需要,任何数×2之后,各位必定是偶数,加1不会引起进位
52 
53 }
54 
55 int main()
56 {
57     int cas;scanf("%d\n",&cas);
58     for(int m=0;m<cas;m++)
59     {
60         int BIGINT[101],bin[335],pos=0,binpos;
61         init(BIGINT);//读入整数
62      //以下开始求整数的二进制形式,并存放在二进制数组中,显然,存放的时候已经是倒序了。
       //pos是整数数组的最高位,binpos记录二进制数组何时结束
       //以整数5432为例 63 for(binpos=0;BIGINT[pos]!=END;binpos++) //一直计算到整数为0(pos达到END处)64 { 65 int rmd=0,divd;             // 66 for(int i=pos;BIGINT[i]!=END;i++)  // i=0         i=1        i=2     i=3 67 {                     // 68 divd=rmd*10+BIGINT[i];      // divd=5        divd=14     divd=3   divd=12 69 rmd=divd%2;             // rmd=5除以2余1    rmd=0      rmd=1    rmd=0 70 BIGINT[i]=divd/2;         // 原5的位置除2后为2  原4位置为7    原3位置为1  原2位置为6 71 }                     //可以看到,一次运算,5432除2得2716,余0,将0存入二进制数组,并更新binpos位置 72 bin[binpos]=rmd;            // 73 if(BIGINT[pos]==0) pos++;     //2716/2=1358,1358/2=678; 此时BIGINT[pos]=0,pos更新,下次计算时,便从6开始了。 74 }                        // 75 bin[binpos]=END;              //标记二进制数组结束位置 76 int out[110],ppos=0;out[0]=bin[0]; 77 for(int i=1;i<110;i++) out[i]=-1; 78 for(int i=1;bin[i]!=END;i++)      //二进制转十进制,从最高位开始*2+后一位,注意这个数组是倒序了的 79 { 80 multiout(out); 81 addout(out,bin[i]); 82 } 83 for(;out[ppos+1]!=-1;ppos++); 84 85 printf("case #%d:\n",m); 86 for(ppos;ppos>=0;ppos--) 87 printf("%d",out[ppos]); 88 printf("\n"); 89 90 } 91 return 0;92 }

 

具体分析看注释。

这题应该算是一个大数的题吧,long long类型最大值在1018,因此用数组保存数据。

 

转载于:https://www.cnblogs.com/Jiiiin/p/8615705.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值