PKU1220
有t组cases。每组给你一个from,to,和串s。将from进制下的串s转化为to进制下的串
这个是个进制转化的问题,如果丢给我,我肯定会用传说中的转10再回转的方。但是对于大数据的话,肯定是过不了的,并且时间复杂度要高很多。
于是就有了下面的方法。
对大数的进制转换,可以不用大数的除法运算。
假设要把一个二进制数1011,转换成一个三进制数。
1、用二进制数的第一位1去除以3,商为0,余数是1
2、由于前面一位的除法结果有余数,所以要把余数*(进制)+该为数字。对于本例,就是1(余数)*2(进制)+0(当前这位的数值)=2。除以3后,商0,余数是2
3、同2所述,2(余数)*2(进制)+1(当前这位的数值)=5。5除以3后,商1,余数2
4、同2所述,2(余数)*2(进制)+1(当前这位的数值)=5。5除以3后,商1,余数2
以上四步可以表示为 1011(2-based) / 3(要转换成的基数) = 0011(2-based 商).. 2(3-based 余数)
然后再让0011除以3,重复以上步骤,直到商为0。每次的余数的逆序就是以3为基的数。
1011/3 -->0011 ..2
0011/3 -->0001 ..0
0001/3 -->0000 ..1
所以,1011(2-based) --> 102(3-based)
代码:#include<iostream>
#include<string>
using namespace std;
string idx="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
int getValue(char ch)//将字符c转换为相对应的数字
{
if(ch>='0'&&ch<='9') return ch-'0';
else if(ch>='A'&&ch<='Z') return ch-'A'+10;
else return ch-'a'+36;
}
//将from进制下的字符串转换为to进制下的整数
string change(string s,int from,int to)
{
string res="";
int r,i,g,t,sum=1,len=s.size();
while(sum!=0) //sum作为循环结束标志
{
r=sum=0;
for(i=0;i<len;i++)
{
t=getValue(s[i]);
sum+=t; //统计各位数字和
g=t+from*r;
s[i]=idx[g/to]; //存储该进制下的商
r=g%to; //除n取余
}
if(sum>0)
res=idx.substr(r,1)+res; //先得到的余数放在低位
}
if(res=="") //result为空串表明转换得到的结果为0
res="0";
return res;
}
int main(){
string s;
int i,t,from,to;
cin>>t;
while( t--){
cin>>from>>to>>s;
cout<<from<<" "<<s<<endl;
cout<<to<<" "<<change(s,from,to)<<endl<<endl;
}
return 0;
}