Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 4909 | Accepted: 2242 |
Description
{ 0-9,A-Z,a-z }
HINT: If you make a sequence of base conversions using the output of one conversion as the input to the next, when you get back to the original base, you should get the original number.
Input
Output
Sample Input
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
Sample Output
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
大数 n 进制转化为m 进制:
第一次接触高精度的进制转换,有点蒙,直接来回短除根本不行,因为高位很可能过对低位有影响(也就是除不尽的情况),得到的数据不一定是正确的数值,然后参观大神的代码,然后没看明白...................脑子笨.....
没办法,借鉴代码自己想了很久,才发现一个突破点! 不能直接短除的原因是高位可能对低位有影响,那么每次计算的时候直接从最高位开始累积计算对下一位的影响,一直计算到最后一位,那么最后一位的数值就是可以直接对m 进行取余和短除的运算了!因为以上位数经过处理后,全部能整除 m,那么下一次对数据进行操作,就不会影响已经计算过的数值了,例如
8 进制 52 转化为 3 进制的数值,那么从最高位考虑
5 代表了5个8,也就是40,这个数据因为对 3 不能整除,那么一定要考虑这一位的影响,那么就把这一位变成不能影响最后一位的数值,也就是三的倍数,那就是3,然后除去3 ,得到最高位转化后的数值,而最后一位的值就是考虑了所有的高位的影响之后的数值,为2*8+2=18,然后对18 进行 除三取余的做法,得到转化的结果最后一位为 0 现在数据变为了 1 6...再次运行,最低位变为 14 ,得到 2 最低位变为 4 ,继续操作,得到1 最低位变为 1 .....然后最后一次就得到了 1 结果为 0 2 1 1 倒序排列 1120 ........
这个思想其实就是除不尽就留到下一位再去除的问题,只是进制不是十进制而已,处理方法算是完全一样.....
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
using namespace std;
int n, m, y[1005];
char x[1005], tb[] = { "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" };
void slove()
{
stack < char >s;
int len = strlen(x);
for (int i = len - 1; i >= 0; --i)
{
int tp = lower_bound(tb, tb + 62, x[i]) - tb;//为了方便,二分一下查找
y[len - i - 1] = tp;
}
int sum = 0,i=0;
while (len>0)
{
for (int j = len-1; j > 0; --j)//每次从最高位下手
{
y[j - 1] += y[j] % m * n;
y[j] /= m;
}
s.push(tb[y[0] % m]);//计算最低位
y[0] /= m;
while (!y[len - 1])//这个是去掉高位的前导零
{
--len;
}
}
while (!s.empty())//输出
{
printf("%c", s.top());
s.pop();
}
printf("\n\n");//注意格式
}
int main()
{
int t;
//freopen("shuju.txt", "r", stdin);
scanf("%d", &t);
while (t--)
{
scanf("%d%d%s", &n, &m, x);
printf("%d %s\n%d ", n, x, m);
slove();
}
return 0;
}