10进制 VS 2进制 (九度oj)
题目
题目描述: 对于一个十进制数A,将A转换为二进制数,然后按位逆序排列,再转换为十进制数B,我们乘B为A的二进制逆序数。 例如对于十进制数173,它的二进制形式为10101101,逆序排列得到10110101,其十进制数为181,181即为173的二进制逆序数。 输入: 一个1000位(即10^999)以内的十进制数。 输出: 输入的十进制数的二进制逆序数。 样例输入: 173 样例输出: 181
思路
这道题花了我将近一天的时间才ac,主要失误在没有考虑大数的n次方,这里讲一下具体的思路和容易出错的地方
- 首先,将十进制字符串A通过大数除法转换成二进制字符串B,参考链接: http://blog.csdn.net/zinss26914/article/details/8640266
- 其次,将二进制字符串B通过大数乘法转换成十进制字符串C,这是关键,我把我的手动推导过程贴上来:
AC代码
#include <stdio.h> #include <string.h> #include <stdlib.h> #define TEN 2000 #define TWO 4000 char A[TEN], B[TWO]; int C[TEN]; int divideToBinary(); void multiplyToDecimal(int k); int main() { int k; while (scanf("%s", A) != EOF) { k = divideToBinary(); multiplyToDecimal(k); } return 0; } int divideToBinary() { int i, k, sum, len, d; memset(B, 0, sizeof(B)); sum = 1; len = strlen(A); k = 0; //转换为2进制 while (sum) { sum = 0; for (i = 0; i < len; i ++) { d = (A[i] - '0') / 2; sum += d; if (i == len - 1) { B[k ++] = (A[i] - '0') % 2 + '0'; }else { A[i + 1] += (A[i] - '0') % 2 * 10; } A[i] = d + '0'; } } B[k] = '\0'; return k; } void multiplyToDecimal(int k) { int i, j, c, len; memset(C, 0, sizeof(C)); len = 1; //搞清楚逆序后的关系,没有必要真正的逆序 for (i = 0; i < k; i ++) { for (j = 0; j < len; j ++) { C[j] *= 2; } C[0] += B[i] - '0'; for (j = c = 0; j < len; j ++) { C[j] += c; if (C[j] >= 10) { c = C[j] / 10; C[j] %= 10; }else { c = 0; } } while (c > 0) { C[j ++] = c % 10; c /= 10; } len = j; } for (i = len - 1; i >= 0; i --) { printf("%d", C[i]); } printf("\n"); } /************************************************************** Problem: 1208 User: wangzhengyi Language: C Result: Accepted Time:50 ms Memory:924 kb ****************************************************************/
后记
最近研究大数乘除法比较多,欢迎各位跟帖讨论!