题意
进制转换。
题解
模拟
一个比较粗暴易懂的方法是像手工做一样,先把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;
}