小生我又来了,原题链接https://www.luogu.com.cn/problem/P1143
输入格式
共三行,第一行是一个正整数,表示需要转换的数的进制n(2≤n≤16),第二行是一个n进制数,若n>10则用大写字母A-F表示数码10-15,并且该n进制数对应的十进制的值不超过1000000000,第三行也是一个正整数,表示转换之后的数的进m(2≤m≤16)。
输出格式
一个正整数,表示转换之后的m进制数。
1、思路分析
输入三个数n、n进制的数、以及待转换的进制m,这里我采用的是把这个数转换成十进制然后再进行处理
由于这个数转换成十进制时需要每一位乘以该位对应的进制数--比如16进制的123,2乘以16^1,1乘以16^2,也就是说对每一位单独处理,所以输入时用char 数组来存(大小超过十亿)方便对每一位进行处理,后面转成int值即可。
用num来存转成的十进制数,为了防止数据溢出,设成long long ,再用一个char数组来存10-15的数的值(ABCDEF)
//全局变量
char a[1000000000];
char c[6] = {'A', 'B', 'C', 'D', 'E', 'F'};
long long n;//代表进制数
int m;//代表转化后的进制
long long num = 0;//用来存该n进制数对应的十进制数
cin >> n;
cin >> a;
cin >> m;
int temp = n;
for(int i = strlen(a) - 1; i >= 0; i--)
{//字符转成对应的十进制数,用num来存总和
if(a[i] >= 65 && a[i] <= 97)
a[i] = a[i] - 55;
else a[i] = a[i] - '0';
num += (n / temp)* a[i];
n = temp * n;
}
由于我们输出应该是求余后的逆序输出,所以这里用while循环求余,余数放进b数组,逆序输出即可
值得注意的是如果输出16进制的时候,余数大于10(也就是输出ABCDEF时)该怎么办,这时候上面预先创建的c数组就体现出作用了:输出 c[余数 - 10] 即可
int i = 0;
int b[200];//全局变量
while(num)//求余循环
{
b[i++] = num % m;
num /= m;
}
for(int j = i - 1; j >= 0; j--)//逆序输出
{
if(b[j] >= 10)
cout << c[b[j] - 10];
else cout << b[j];
}
上面用main函数整合一下就可以AC了
#include<iostream>
#include<cstring>
using namespace std;
int b[200];
char a[1000000000];
char c[6] = {'A', 'B', 'C', 'D', 'E', 'F'};
int main()
{
long long n;//代表进制数
int m;//代表转化后的进制
long long num = 0;//用来存该n进制数对应的十进制数
cin >> n;
cin >> a;
cin >> m;
int temp = n;
for(int i = strlen(a) - 1; i >= 0; i--)
{
if(a[i] >= 65 && a[i] <= 97)
a[i] = a[i] - 55;
else a[i] = a[i] - '0';
num += (n / temp)* a[i];
n = temp * n;
}
int i = 0;
while(num)
{
b[i++] = num % m;
num /= m;
}
for(int j = i - 1; j >= 0; j--)
{
if(b[j] >= 10)
cout << c[b[j] - 10];
else cout << b[j];
}
return 0;
}
我们下次再见!