题目链接:https://vjudge.net/problem/POJ-1220
题意:给定a进制的大数s,将其转换为b进制。其中2<=a,b<=62。
题意:一般进制转换是以10进制为中介进行转换,但这里的s太大了,大概10^500,如果要转换十进制来算必须要手写高精度模板或者用Java的API。这里我用的短除法,复杂度比较小。原理大致是将s每次除以b,得到的余数的逆序列是b进制表示的结果。每次除的时候用到同余模定理,即从最高位开始除,得到的余数乘以a加到下一位,一直到最低位。
AC代码:
#include<cstdio> #include<cstring> using namespace std; int a,b,T,t1[1005],t2[1005]; char s[1005]; int main(){ scanf("%d",&T); while(T--){ scanf("%d%d%s",&a,&b,s); int len=strlen(s); for(int i=0;i<len;++i){ if(s[i]>='A'&&s[i]<='Z') t1[len-1-i]=s[i]-'A'+10; else if(s[i]>='a'&&s[i]<='z') t1[len-1-i]=s[i]-'a'+36; else t1[len-1-i]=s[i]-'0'; } int k=0; while(len){ for(int i=len-1;i>0;--i){ t1[i-1]+=t1[i]%b*a; t1[i]/=b; } t2[k++]=t1[0]%b; t1[0]/=b; while(len&&!t1[len-1]) --len; } printf("%d %s %d ",a,s,b); for(int i=k-1;i>=0;--i){ if(t2[i]>=0&&t2[i]<=9) printf("%d",t2[i]); else if(t2[i]>=10&&t2[i]<=35) printf("%c",t2[i]-10+'A'); else printf("%c",t2[i]-36+'a'); } printf(" "); } return 0; }
附上Java代码(219ms,4528KB):
import java.io.*; import java.math.*; import java.util.*; public class Main{ public static void main(String args[]){ Scanner cin=new Scanner(System.in); int T; BigInteger a,b,sum; T=cin.nextInt(); while((T--)!=0){ a=cin.nextBigInteger(); b=cin.nextBigInteger(); String s=cin.next(); sum=BigInteger.valueOf(0); for(int i=0;i<s.length();++i){ char c=s.charAt(i); int tmp; if(c>='0'&&c<='9') tmp=c-'0'; else if(c>='A'&&c<='Z') tmp=c-'A'+10; else tmp=c-'a'+36; sum=sum.multiply(a); sum=sum.add(BigInteger.valueOf(tmp)); } BigInteger zero=BigInteger.valueOf(0); int ans[]=new int[1005]; int k=0; while(sum.compareTo(zero)!=0){ ans[k++]=sum.mod(b).intValue(); sum=sum.divide(b); } System.out.print(a+" "+s+" "+b+" "); if(k==0) System.out.print(0); //注意为0的情况 for(int i=k-1;i>=0;--i){ int tmp=ans[i]; char c; if(tmp<=9) c=(char)('0'+tmp); else if(tmp<=35) c=(char)('A'+tmp-10); else c=(char)('a'+tmp-36); System.out.print(c); } System.out.print(" "); } } }