【清华机试】10进制 VS 2进制

来源:互联网 发布:asp源码绑定域名代码 编辑:程序博客网 时间:2024/04/30 17:22

题目描述
对于一个十进制数A,将A转换为二进制数,然后按位逆序排列,再转换为十进制数B,我们乘B为A的二进制逆序数。 例如对于十进制数173,它的二进制形式为10101101,逆序排列得到10110101,其十进制数为181,181即为173的二进制逆序数。
输入
一个1000位(即10^999)以内的十进制数。
输出
输入的十进制数的二进制逆序数。
样例输入
173
样例输出
181
思路分析

  1. 由于输入有1000位,则应将初始输入存储到字符串中;
  2. 本解法采用模2取余的方法求输入数字的2进制表达形式;
  3. 2进制转换成10进制的过程中采用普通大数加法的形式;

代码

/**    参考 CSDN Blog : http://blog.csdn.net/sjf0115/article/details/8690581*/#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int maxn = 4000;  // 因为输入的10进制不超过1000位,则转换成2进制应该不超过4000位(2^4 = 16)const int oldBase = 10; // 原始进制const int newBase = 2;  // 新进制string str;             // 因为输入为不超过1000位的10进制数则应该用字符串接收/**    数组的 0 号元素均用于存储数组的长度*/int br[maxn] = {0};     // 存储2进制int dr[maxn] = {0};     // 存储10进制int drans[maxn] = {0};  // 存储10进制转2进制的过程中的商,并且存储将 2 进制转换到 10 进制的过程中 的2^nint drres[maxn] = {0};  // 存储10进制转2进制的过程中的余数// 将 字符串 str 存到 dr int数组中, dr[0] 记录10进制数组长度void change(){    memset(dr, 0, sizeof(dr));    dr[0] = 0;      // 使用 dr[0] 存储数组长度    for(int i = 1; i <= str.length(); ++i)    {        dr[++dr[0]] = str[i-1]-'0';    }}// 将 10 进制转换成 2 进制void solve(){    memset(drres, 0, sizeof(drres));    int y, i, j, k;    // 模 n 取余法,(总体规律是先余为低位,后余为高位)    while(dr[0] >= 1)    {        // 只要被除数仍然 >= 1,则继续操作        y = 0;        i = 1;        drans[0] = dr[0];       // 商的长度与被除数相同(包含前导0)        while(i <= dr[0])        {            y = y * oldBase + dr[i];            drans[i++] = y / newBase;            y %= newBase;        }        drres[++drres[0]] = y;  // 本轮计算得到的余数        i = 1;        // 找到下一轮商的起始位置        while((i<=drans[0]) && (drans[i] == 0)) ++i;        // 清除这一轮使用的被除数        memset(dr, 0, sizeof(dr));        // 本轮得到的商为下一轮的被除数        for(j = i; j <= drans[0]; ++j)        {            dr[++dr[0]] = drans[j];        }        // 清除本轮的商        memset(drans, 0, sizeof(drans));    }    /**        现在 drres 存储的是 str 的 2 进制的倒序,即题目中要求的二进制序列        下面将 drres 中存储的 2 进制(1~drres[0]),转换成 10 进制并存储到 dr 中    */    memset(drans, 0, sizeof(drans));    memset(dr,0,sizeof(dr));    drans[0] = 1;    drans[1] = 1;   // 2^0 = 1;    for(i = drres[0]; i >= 1; --i)    {        // 先 + ,后计算 2 ^ n        if(drres[i] == 1)        {            // dr[0] 取 dr[0] 原以及 drans[0] 取两者较大者,为了保持数据位数            dr[0] = dr[0] > drans[0] ? dr[0] : drans[0];            // 此为为 1 才加            for(k = 1; k <= drans[0]; ++k)            {                dr[k] += drans[k];            }            // 移位            for(j = 1; j <= dr[0]; ++j)            {                if(dr[j] > 9)                {                    dr[j+1] += dr[j] / oldBase;                    dr[j] %= oldBase;                    // 最高位进位的情况                    if(dr[0] == j)                    {                        ++dr[0];                    }                }            }        }        // 计算 2 ^ n        for(j = 1; j <= drans[0]; ++j)        {            drans[j] *= newBase;        }        // 移位        for(j = 1; j <= drans[0]; ++j)        {            if(drans[j] > 9)            {                drans[j+1] += drans[j] / oldBase;                drans[j] %= oldBase;                // 最高位进位的情况                if(drans[0] == j)                {                    ++drans[0];                }            }        }    }}void output(){    for(int i = dr[0]; i > 0; --i)    {        cout << dr[i];    }}int main(){    while(cin >> str)    {        change();       // 将10进制数据存储到数组中        solve();        // 将 10 进制转换成 2 进制,并将其 2 进制倒序所表示的 10 进制存储到原数组中        output();       // 输出        cout << endl;     }    return 0;}
0 0
原创粉丝点击