题目描述
将M进制的数X转换为N进制的数输出。
输入描述:
输入的第一行包括两个整数:M和N(2<=M,N<=36)。 下面的一行输入一个数X,X是M进制的数,现在要求你将M进制的数X转换成N进制的数输出。
输出描述:
输出X的N进制表示的数。
示例1
输入
10 2 11
输出
1011
备注:
注意输入时如有字母,则字母为大写,输出时如有字母,则字母为小写。
本题中的m、n范围是2~36,显然是用了超过十进制的用26个字母表示,因此最多是到36进制,而二进制到十进制中间各种进制的转换,只是涉及到0~9数字之间的排列,但是十一进制到三十六进制之间,则会出现26个字母,因此需要区分看待。
本题中可以通过十进制作为中间过渡,实现M到十进制转换,十进制到N进制的转换
总结:本题在做时只能想到最简单易懂的方法,按照部分功能测试成功后,最后将程序跑成功,发现其实其中进制转换的四个函数分为两组中,代码的重复度较大,还没想出来如何去优化,请大神不吝指教;
在提交过程中发下只有66%的通过率,其中 36 9 数据会发生错误,仔细观察尝试后发现可能是函数Down or Up转十进制的函数中的result可能会产生溢出,并将其相关变量改为long long 型予以解决
完全是个人想法作为笔记来用,谢谢
后附有牛客上的OJ
#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
using namespace std;
//中间用十进制的过渡
long long DowntoTen(string str,int m)
{ //低于十进制的转换成十进制
long long result=0;
for(int i=0;i<str.size();i++)
{
result=result*m+str[i]-'0';
}
return result;
}
long long UptoTen(string str,int m)
{ //高于十进制的转换成十进制
long long result =0;
for(int i=0;i<str.size();i++)
{
if(str[i]>='0'&&str[i]<='9')
result=result*m+str[i]-'0';
else result=result*m+str[i]-'A'+10;
}
return result;
}
void TentoDown(long long ten,int n)
{ //十进制转低成于十进制
int a[100];
int i=0,j;
while(ten!=0){
a[i++]=ten%n;
ten=ten/n;
}
for(j=i-1;j>=0;j--)
cout<<a[j];
cout<<endl;
}
void TentoUp(long long ten,int n){
//十进制转高成于十进制
char a[100];
int i=0,j;
int t;
while(ten!=0)
{
t=ten%n;
if(t>=10)
{
a[i]=t-10+'A'; //是26个字母的
}
else a[i]=t+'0'; //不是26个字母的
ten=ten/n;
i++;
}
for(j=i-1;j>=0;j--) //逆序输出
cout<<a[j];
cout<<endl;
}
int main()
{
int m,n;
string str;
while(scanf("%d%d",&m,&n)!=EOF)
{
cin>>str;
long long t;
if(m>=2&&m<=10){
//小于十进制
t=DowntoTen(str,m);
if(n>=2&&n<=10) //转成不大于十进制
TentoDown(t,n);
else{
//转成大于十进制
TentoUp(t,n);
}
}
else{
//高于十进制
t=UptoTen(str,m);
if(n>=2&&n<=10) //输出要求低于十进制
TentoDown(t,n);
else TentoUp(t,n); //输出要求高于十进制
}
}
}