天天看点

EOJ 3031 二进制倒置

题目描述

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

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

Input

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

接下来共 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