poj1220 Number Base Conversion(模拟)

题意

进制转换。

 

题解

模拟

一个比较粗暴易懂的方法是像手工做一样,先把p进制转为10进制,再用短除法转为q进制。这样会涉及高精度加、乘、除(高精除低精),比较麻烦。
要注意到,高精度间的运算是没有进制限制的。所以在一开始,我们就可以把全部运算切换到q进制下进行。
相当于我们把p进制数分解时,不以10进制为记录其数的进制,而是在运算中直接%q,将其切换乘q进制。
如果不懂的可以看代码。

 

小结

数字是显示物体量的一个符号,它本身是没有进制的,只在表示时才有进制问题。在高精度中,只是量之间的加减乘除,就是不存在进制的一个表现,所以经高精度计算后的数可以随意切换成任意进制,注意仅仅是表示的问题!

 

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

char ic[150];//ic[int]=char
int ci[150];//ci[char]=int

int p,q;
char s[1010];
struct B
{
    int len,a[1010];
    B()
    {
        len=1;memset(a,0,sizeof(a));
    }
    void init(int x)
    {
        len=0;
        while(x)
        {
            a[++len]=x%10;
            x/=10;
        }
        if(len==0) len=1;
    }
    void print()
    {
        for(int i=len;i>=1;i--) printf("%c",ic[a[i]]);
        printf("\n");
    }
    B operator +(B x)//以下的运算都在q进制下进行 
    {
        B re;
        re.len=max(len,x.len);
        for(int i=1;i<=re.len;i++)
        {
            re.a[i]+=a[i]+x.a[i];
            if(re.a[i]>=q)
            {
                re.a[i+1]+=re.a[i]/q;
                re.a[i]%=q;
            }
        }
        while(re.a[re.len+1]>0)
        {
            re.len++;
            re.a[re.len+1]+=re.a[re.len]/q;
            re.a[re.len]%=q;
        }
        return re;
    }
    B operator *(int x)
    {
        B re;
        re.len=len;
        for(int i=1;i<=len;i++)
        {
            re.a[i]+=a[i]*x;
            if(re.a[i]>=q)
            {
                re.a[i+1]+=re.a[i]/q;
                re.a[i]%=q;
            }
        }
        while(re.a[re.len+1]>0)
        {
            re.len++;
            re.a[re.len+1]+=re.a[re.len]/q;
            re.a[re.len]%=q;
        }
        return re;
    }
};

int main()
{
    for(int i='0';i<='9';i++) ci[i]=i-'0';
    for(int i='A';i<='Z';i++) ci[i]=i-'A'+10;
    for(int i='a';i<='z';i++) ci[i]=i-'a'+36;
    
    for(int i=0;i<=9;i++) ic[i]='0'+i;
    for(int i=10;i<=35;i++) ic[i]='A'+i-10;
    for(int i=36;i<=61;i++) ic[i]='a'+i-36;
    
    int n;scanf("%d",&n);
    while(n--)
    {
        B a,b,t;
        
        scanf("%d%d",&p,&q);
        scanf("%s",s+1);
        printf("%d %s\n",p,s+1);
        
        a.len=strlen(s+1);
        for(int i=1;i<=a.len;i++) a.a[i]=ci[s[a.len-i+1]];
        t.init(1);
        for(int i=1;i<=a.len;i++)//像转成10进制一样转换 
        {
            b=b+t*a.a[i];
            t=t*p;
        }
        printf("%d ",q);
        b.print();
        printf("\n");
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值