1220 NUMBER BASE CONVERSION【高精度进制转化】

10 篇文章 0 订阅

NUMBER BASE CONVERSION
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 4909 Accepted: 2242

Description

Write a program to convert numbers in one base to numbers in a second base. There are 62 different digits: 
{ 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

The first line of input contains a single positive integer. This is the number of lines that follow. Each of the following lines will have a (decimal) input base followed by a (decimal) output base followed by a number expressed in the input base. Both the input base and the output base will be in the range from 2 to 62. That is (in decimal) A = 10, B = 11, ..., Z = 35, a = 36, b = 37, ..., z = 61 (0-9 have their usual meanings). 

Output

The output of the program should consist of three lines of output for each base conversion performed. The first line should be the input base in decimal followed by a space then the input number (as given expressed in the input base). The second output line should be the output base followed by a space then the input number (as expressed in the output base). The third output line is blank. 

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值