题目描述
编写一个程序,可以实现将一个数字由一个进制转换为另一个进制。
这里有62个不同数位{0-9,A-Z,a-z}。
输入格式
第一行输入一个整数,代表接下来的行数。
接下来每一行都包含三个数字,首先是输入进制(十进制表示),然后是输出进制(十进制表示),最后是用输入进制表示的输入数字,数字之间用空格隔开。
输入进制和输出进制都在2到62的范围之内。
(在十进制下)A = 10,B = 11,…,Z = 35,a = 36,b = 37,…,z = 61 (0-9仍然表示0-9)。
输出格式
对于每一组进制转换,程序的输出都由三行构成。
第一行包含两个数字,首先是输入进制(十进制表示),然后是用输入进制表示的输入数字。
第二行包含两个数字,首先是输出进制(十进制表示),然后是用输出进制表示的输入数字。
第三行为空白行。
同一行内数字用空格隔开。
样例
输入样例:
8
62 2 abcdefghiz
10 16 1234567890123456789012345678901234567890
16 35 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2
35 23 333YMHOUE8JPLT7OX6K9FYCQ8A
23 49 946B9AA02MI37E3D3MMJ4G7BL2F05
49 61 1VbDkSIMJL3JjRgAdlUfcaWj
61 5 dl9MDSWqwHjDnToKcsWE1S
5 10 42104444441001414401221302402201233340311104212022133030
输出样例:
62 abcdefghiz
2 11011100000100010111110010010110011111001001100011010010001
10 1234567890123456789012345678901234567890
16 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2
16 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2
35 333YMHOUE8JPLT7OX6K9FYCQ8A
35 333YMHOUE8JPLT7OX6K9FYCQ8A
23 946B9AA02MI37E3D3MMJ4G7BL2F05
23 946B9AA02MI37E3D3MMJ4G7BL2F05
49 1VbDkSIMJL3JjRgAdlUfcaWj
49 1VbDkSIMJL3JjRgAdlUfcaWj
61 dl9MDSWqwHjDnToKcsWE1S
61 dl9MDSWqwHjDnToKcsWE1S
5 42104444441001414401221302402201233340311104212022133030
5 42104444441001414401221302402201233340311104212022133030
10 1234567890123456789012345678901234567890
高精度+进制转换
相信一部分的大佬们,都会认为这道题目要先转移到十进制,然后再转移到目标进制.不过这里提出一个比较有趣的精简代码,我们发现其实这个初始进制到十进制是可以省略到的,我们可以直接从初始进制运算到到目标进制,十进制只是一个跳板.
高精度,就是高精度乘上低精度的乘法,因为进制转换需要用到
C++ 代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1100;
#define fir(a,b,c) for (int a=b;a<=c;a++)
int t[maxn],A[maxn],n,m,i,len,k;
char str1[maxn], str2[maxn];
void solve()
{
k=0;
len = strlen(str1);
for(i=len; i>=0; i--)
t[len-i-1] = str1[i] -(str1[i]<58 ? 48: str1[i]<97 ? 55: 61);//开始转换成为十进制
while(len)
{
for(i=len; i>=1; i--)
{
t[i-1] +=t[i]%m*n;//开始计算,首先*n,为n进制,然后转移到m进制
t[i] /= m;//当前数已经处理完了
}
A[k++] = t[0] % m;//直接加到答案数组中
t[0] /=m;//当前数已经处理完了
while(len>0&&!t[len-1]) //处理0的情况
len--;
}
str2[k] =NULL;//第k位,我们不需要,直接抛去,利用NULL这个特殊的字符串结束符,具体可以自行百度.
fir(i,0,k-1)
str2[k-1-i] = A[i]+(A[i]<10 ? 48: A[i]<36 ? 55:61);//三目运算符,具体可以百度,这段代码的意思是,找这个数字对应的字母
}
int main()
{
int t;
scanf("%d\n",&t);
while(t--)
{
scanf("%d %d %s\n",&n,&m,str1);
solve();
printf("%d %s\n%d %s\n\n",n,str1,m,str2);
}
return 0;
}
请问这个转换法是什么原理,看了好几天了还是不懂
我…我需要高精模板
题目中有的,只不过我每没有截取了。
真要用高精啊,太狠了
狼灭
是啊。
res为什么不用考虑前导零
排除了
我觉得没有从-1开始的循环啊? i=len len = strlen(str1); str1 每次循环都会输入字符串 长度不为0
c支持-1 下标存疑。
另外我觉得没有从-1开始的循环啊?
-1其实可以的.
第一个循环,len-1-i,值从-1开始?t[-1]为什么不报错?
的确是不报错的,我看了看C编辑器,一些入门书上会说报错,但实际上-1是有存储空间地址的,C是支持-1下标的.