EOJ 3031:二进制倒置(高精度乘+高精度除+进制转换)

一、思路:

1.读入:字符数组s读入->整型数组a存储十进制->整型数组b存储二进制

2.高精度÷单精度:模拟除法+去除前导零(On)

3.高精度×单精度:模拟乘法+向后开辟新位置(On^2)

4.输出

二、存储变量:

char s[ ]: 读取字符

int a[ ]: 按位存储十进制

int b[ ]: 按位存储倒置的二进制

int len: a[ ]的位数

int lenb: b[ ]的位数 

三、几个复杂的点

1.消除前导零:int pos=1 模拟单指针遍历数组a,zeroNum++,直至遇到非零退出循环;对数组a 整体进行前移,前移zeroNum位 (On)

2.二进制转十进制:设b1b2……bn为二进制表示,设对应的十进制为deci=0,deci算法:乘以2再加1;

四、代码

#include <bits/stdc++.h>
using namespace std;
//3031: high precision

char s[105];
int T, cnt, len;//set len as a global variable so that it can be easily accessed by function
int a[105], b[340];

//high precision ÷ integer
void div(int a[])
{
    for(int i=1;i<len;++i)
    {
        if(a[i]%2==0) a[i]/=2;
        else a[i+1]+=10,a[i]/=2;
    }
    a[len]/=2;//a[len] is handled singly

    //remove the front 0
    int pos=1;
    int zeroNum=0;
    while(pos<=len&&a[pos]==0){
        zeroNum++;
        pos++;
    }
    for(int i=1;i<=len-zeroNum;++i)
        a[i]=a[i+zeroNum];//array data migration
    len-=zeroNum;
}

//high precision × integer
void multi(int a[])
{
    //simulate vertical multiplication
    for(int i=len;i>=1;--i)
        a[i]*=2;
    for(int i=len;i>=1;--i){
        a[i-1]+=a[i]/10;
        a[i]%=10;
    }

    //handle carry problem
    if(a[0]>0){
        len++;
        for(int i=len;i>=1;--i)
            a[i]=a[i-1];
        a[0]=0;
    }
}
int main()
{
    scanf("%d",&T);
    while(T--){
        //input: char array -> int array
        scanf("%s",s+1);
        len=strlen(s+1);
        for(int i=1;i<=len;++i)
            a[i]=s[i]-'0';

        //decimal -> binary algorithm
        //div function
        int p=1;
        while(len>0){
            b[p++]=a[len]%2;
            div(a);
        }

        //binary -> decimal algorithm
        //multi function
        int lenb=p-1;
        memset(a,0,sizeof(a));
        a[1]=0, len=1;
        for(int i=1;i<=lenb;++i){
            multi(a);
            if(b[i]) a[len]+=1;
        }

        //output
        printf("case #%d:\n",cnt++);
        for(int i=1;i<=len;++i)
           cout<<a[i];
        cout<<endl;
    }
    return 0;
}
/*
3
10
0
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
*/

 

转载于:https://www.cnblogs.com/ChenyangXu/p/10461130.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值