题目大意:给出两个进制oldBase 和newBase, 以及以oldBase进制存在的数。要求将这个oldBase进制的数转换成newBase进制的数。
解决方式是短除法;
对8进制数number 454 转为10进制数 ,number 长度为len
-----------------------------
那么先对number 的前len-1位去短除10;
ans[i]=ans[i]/10;
并且把余数传递给下一位 ans[i-1]+=ans[i]%10*8;
---------------------------
现在剩下最后一位ans[0]我们还没处理,显然ans[0]%b就是 用number去短除10得到的第一个余数 ,我们存起来,并且ans[0]/=10;
---------------------------
至此我们得到了number短除进制数10的第一个余数,并且得到的商存在ans数组,我们可以先把ans数组的前导零去掉;
然后反复循环这个步骤,直到短除得到的商(ans数组全为零)
最终得到的余数逆序输出就是转换得到的NewBase数了。
(注意要处理10及以上的数与字母间的关系)
参考code:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
int ans[100005];
char final[100005];
char s[100005];
__int64 c_to_n(char x)
{
if (x>='0'&&x<='9')
return x-'0';
if (x>='a'&&x<='z')
return x-'a'+36;
if (x>='A'&&x<='Z')
return x-'A'+10;
}
char n_to_c(__int64 x)
{
if (x>=0&&x<=9)
return x+'0';
if (x>=36&&x<=61)
return x+'a'-36;
if (x>=10&&x<=35)
return x+'A'-10;
}
int chg(char s[],int ans[],__int64 a,__int64 b)
{
__int64 res=0,len=strlen(s),i;
__int64 tmp;
char tem;
for (i=0;i<len;i++)
{
ans[i]=c_to_n(s[i]);
}
int k=0;
int j=len;
for (;j;)
{
for (i=j;i>=1;i--)
{
ans[i-1]+=ans[i]%b*a;
ans[i]=ans[i]/b;
}
final[k++]=ans[0]%b;//ans[0]取模得到的就是a进制数S模b的第一个余数
ans[0]/=b; //去掉余数部分
for(;j>0&&!ans[j-1];j--);//去掉前导零
}
return k;
}
int main()
{
__int64 a,b;
int t=100;
cin>>t;
while(t--)
{
scanf("%I64d%I64d %s",&a,&b,s);
int i;
printf("%I64d %s\n",a,s);
int ll=strlen(s);
for (i=0;i<ll/2;i++)
swap(s[i],s[ll-i-1]); //反转顺序
int len=chg(s,ans,a,b);
printf("%I64d ",b);
int tmp;
for (i=len-1;i>=0;i--)
printf("%c",final[i]+(final[i]<10?'0':(final[i]<36?55:61)) );
printf("\n\n");
}
return 0;
}