九度oj 题目1208:10进制 VS 2进制

题目描述:

    对于一个十进制数A,将A转换为二进制数,然后按位逆序排列,再转换为十进制数B,我们乘B为A的二进制逆序数。
    例如对于十进制数173,它的二进制形式为10101101,逆序排列得到10110101,其十进制数为181,181即为173的二进制逆序数。

输入:

    一个1000位(即10^999)以内的十进制数。

输出:

    输入的十进制数的二进制逆序数。

样例输入:
173
样例输出:
181

初看此题,本以为是一道水题。但仔细一看是1000位的整数,难度瞬间提高了好几个档次。
没办法,用处理长整数的办法解题吧!
  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <string>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <cmath>
  7 #define MAX 1009
  8 #define inf 1000000009
  9 #define BASE 4
 10 char temp[MAX];
 11 int src[252];
 12 int des[252];
 13 int tmp[252];
 14 
 15 int div(int toD[], int len) {
 16     if(len == 1) {
 17         toD[0] = toD[0]/2;
 18         return len;
 19     }
 20 
 21     int ci = toD[len-1];
 22     int j = 0;
 23     for(int i = len-2; i >= 0; i--) {
 24         int q = ci * 10000 + toD[i];
 25         int p = q/2;
 26         ci = q%2;
 27         tmp[j] = p;
 28         j++;
 29     }
 30     int t = 0;
 31     for(int v = j-1; v >= 1; v--) {
 32         toD[t++] = tmp[v];
 33     }
 34     
 35     int p = tmp[0] / 10000;
 36     int q = tmp[0] % 10000;
 37     toD[t++] = q;
 38     if(p != 0) {
 39         toD[t++] = p;
 40     }
 41     
 42     return t;
 43 }
 44 
 45 int mul2(int toM[], int len) {
 46     int ci = 0;
 47     for(int i = 0; i < len; i++) {
 48         int p = toM[i] * 2 + ci;
 49         int q = p % 10000;
 50         ci = p/10000;
 51         toM[i] = q;
 52     }
 53     if(ci != 0) {
 54         toM[len] = ci;
 55         len++;
 56     }
 57     
 58     return len;
 59 }
 60 
 61 int inc(int toM[], int len) {
 62     int ci = 0;
 63     for(int i = 0; i < len; i++) {
 64         int p = toM[i] + 1 + ci;
 65         int q = p % 10000;
 66         ci = p/10000;
 67         toM[i] = q;
 68         if(ci == 0) {
 69             return len;
 70         }
 71     }
 72     toM[len] = ci;
 73     len++;
 74     return len;
 75 }
 76 
 77 int main(int argc, char const *argv[])
 78 {
 79     
 80     //freopen("input.txt","r",stdin);
 81     while(scanf("%s",temp) != EOF) {
 82         int k = 0;
 83         memset(src, 0, sizeof(src));
 84         int i = strlen(temp)-1;
 85         for(;i > BASE-1; i = i-BASE) {
 86             for(int j = i - BASE+1; j <= i; j++) {
 87                 src[k] = 10 * src[k] + (temp[j] - '0');
 88             }
 89             k++;
 90         }
 91         for(int j = 0; j <= i; j++) {
 92             src[k] = 10 * src[k] + (temp[j] - '0');
 93         }
 94         k++;
 95         /*for(int i = k-1; i >= 0; i--) {
 96             printf("%04d",src[i]);
 97         }
 98         printf("
");*/
 99         memset(des, 0, sizeof(des));
100         int lend = 1;
101         while(true) {
102             if((src[0]&1 )== 0) {
103                 //des = des * 2;
104                 lend = mul2(des, lend);
105                 //printf("0");
106             }
107             else {
108                 //des = des * 2 + 1;
109                 lend = mul2(des, lend);
110                 lend = inc(des,lend);
111                 //printf("1");
112             }
113             
114             
115             k = div(src, k);
116             
117             /*for(int i = k-1; i >= 0; i--) {
118                 printf("%04d",src[i]);
119             }
120             printf("
");*/
121             
122             if(k == 1 && src[0] == 0) {
123                 break;
124             }
125         }
126         //printf("
");
127         printf("%d",des[lend-1]);
128         for(int i = lend-2; i >= 0; i--) {
129             printf("%04d",des[i]);
130         }
131         printf("
");
132     }
133     return 0;
134 }

代码先将输入的字符串转化为4个一单位的整数数组,之后模拟了整数的除法和乘2操作以及加1操作。

代码提交了两次才通过。原因是第一次在处理除法时偷懒,使最高位可以大于4位,导致错误

原文地址:https://www.cnblogs.com/jasonJie/p/5736000.html