LG-P1017 进制转换

P1017 进制转换
题目链接
题目描述
我们可以用这样的方式来表示一个十进制数: 将每个阿拉伯数字乘以一个以该数字所处位置的(值减1)为指数,以10为底数的幂之和的形式。例如:123可表示为 1 ∗ 1 0 2 + 2 ∗ 1 0 1 + 3 ∗ 1 0 0 1*10^2+2*10^1+3*10^0 1102+2101+3100 这样的形式。

与之相似的,对二进制数来说,也可表示成每个二进制数码乘以一个以该数字所处位置的(值-1)为指数,以2为底数的幂之和的形式。一般说来,任何一个正整数R或一个负整数-R都可以被选来作为一个数制系统的基数。如果是以R或-R为基数,则需要用到的数码为 0,1,…R-1。例如,当R=7时,所需用到的数码是0,1,2,3,4,5和6,这与其是R或-R无关。如果作为基数的数绝对值超过1010,则为了表示这些数码,通常使用英文字母来表示那些大于9的数码。例如对16进制数来说,用A表示10,用B表示11,用C表示12,用D表示13,用E表示14,用F表示15。

在负进制数中是用 -R 作为基数,例如-15(十进制)相当于110001110001(-2进制),并且它可以被表示为22的幂级数的和数:

110001 = 1 ∗ ( − 2 ) 5 + 1 ∗ ( − 2 ) 4 + 0 ∗ ( − 2 ) 3 + 0 ∗ ( − 2 ) 2 + 0 ∗ ( − 2 ) 1 + 1 ∗ ( − 2 ) 0 110001=1*(-2)^5+1*(-2)^4+0*(-2)^3+0*(-2)^2+0*(-2)^1 +1*(-2)^0 110001=1(2)5+1(2)4+0(2)3+0(2)2+0(2)1+1(2)0
设计一个程序,读入一个十进制数和一个负进制数的基数, 并将此十进制数转换为此负进制下的数:-R∈{-2,-3,-4,…,-20}
输入格式:
输入的每行有两个输入数据。

第一个是十进制数N (32768≤N≤32767)
第二个是负进制数的基数-R。

输出格式:
结果显示在屏幕上,相对于输入,应输出此负进制数及其基数,若此基数超过10,则参照16进制的方式处理。

输入样例 #1:
30000 -2
输出样例 #1:
30000=11011010101110000(base-2)
输入样例 #2:
-20000 -2
输出样例 #2:
-20000=1111011000100000(base-2)
输入样例 #3:
28800 -16
输出样例 #3:
28800=19180(base-16)
输入样例 #4:
-25000 -16
输出样例 #4:
-25000=7FB8(base-16)
说明
NOIp2000提高组第一题

题解
这题让我们深究一下进制转换背后的秘密。

任何一个整数数在 R 进制下表现为 a n ∗ R n + a n − 1 ∗ R n − 1 + . . . + a [ 1 ] ∗ R 1 + a [ 0 ] ∗ R 0 a_n*R^n+a_{n-1}*R^{n-1}+...+a[1]*R^1+a[0]*R^0 anRn+an1Rn1+...+a[1]R1+a[0]R0
我们的任务其实就是求出每个 a i a_i ai

根据题目描述中的例子(小一点,输入样例2万3万的玩儿不起)
− 1 5 ( 10 ) = 11000 1 ( − 2 ) = 1 ∗ ( − 2 ) 5 + 1 ∗ ( − 2 ) 4 + 0 ∗ ( − 2 ) 3 + 0 ∗ ( − 2 ) 2 + 0 ∗ ( − 2 ) 1 + 1 ∗ ( − 2 ) 0 -15_{(10)}=110001_{(-2)}=1*(-2)^5+1*(-2)^4+0*(-2)^3+0*(-2)^2+0*(-2)^1 +1*(-2)^0 15(10)=110001(2)=1(2)5+1(2)4+0(2)3+0(2)2+0(2)1+1(2)0
− 1 5 ( 10 ) = 11000 1 ( − 2 ) = a 5 ∗ ( − 2 ) 5 + a 4 ∗ ( − 2 ) 4 + a 3 ∗ ( − 2 ) 3 + a 2 ∗ ( − 2 ) 2 + a 1 ∗ ( − 2 ) 1 + a 0 ∗ ( − 2 ) 0 -15_{(10)}=110001_{(-2)}=a_5*(-2)^5+a_4*(-2)^4+a_3*(-2)^3+a_2*(-2)^2+a_1*(-2)^1 +a_0*(-2)^0 15(10)=110001(2)=a5(2)5+a4(2)4+a3(2)3+a2(2)2+a1(2)1+a0(2)0
显然, − 15    m o d   − 2 -15\ \ mod\ -2 15  mod 2 即为我们想要的 a 0 a_0 a0
接下来,由于 a 0 a_0 a0 已知,代入后移项得:
− 15 − 1 ∗ ( − 2 ) 0 = a 5 ∗ ( − 2 ) 5 + a 4 ∗ ( − 2 ) 4 + a 3 ∗ ( − 2 ) 3 + a 2 ∗ ( − 2 ) 2 + a 1 ∗ ( − 2 ) 1 -15-1*(-2)^0=a_5*(-2)^5+a_4*(-2)^4+a_3*(-2)^3+a_2*(-2)^2+a_1*(-2)^1 151(2)0=a5(2)5+a4(2)4+a3(2)3+a2(2)2+a1(2)1
− 16 = a 5 ∗ ( − 2 ) 5 + a 4 ∗ ( − 2 ) 4 + a 3 ∗ ( − 2 ) 3 + a 2 ∗ ( − 2 ) 2 + a 1 ∗ ( − 2 ) 1 -16=a_5*(-2)^5+a_4*(-2)^4+a_3*(-2)^3+a_2*(-2)^2+a_1*(-2)^1 16=a5(2)5+a4(2)4+a3(2)3+a2(2)2+a1(2)1
两边同时约去 -2
− 8 = a 5 ∗ ( − 2 ) 4 + a 4 ∗ ( − 2 ) 3 + a 3 ∗ ( − 2 ) 2 + a 2 ∗ ( − 2 ) 1 + a 1 ∗ ( − 2 ) 0 -8=a_5*(-2)^4+a_4*(-2)^3+a_3*(-2)^2+a_2*(-2)^1+a_1*(-2)^0 8=a5(2)4+a4(2)3+a3(2)2+a2(2)1+a1(2)0
这个式子又回到了刚才的形式。我们可以继续操作,直到求出 a 5 a_5 a5

代码

#include
#define LL long long
LL n,R;
int len,yu;
char a[10000];
int main()
{
	scanf("%lld%lld",&n,&R);printf("%lld=",n);
	for (len=0;n!=0;++len)
	{
		yu=(n%R-R)%R;
		if (yu<10) a[len]=yu+'0';else a[len]=yu+'A'-10;
		n-=yu*e;
		n/=R;
	}
	for (--len;len>=0;--len) printf("%c",a[len]);
	printf("(base%d)",R);
	return 0;
}

你可能感兴趣的:(日常小题,-,2018,数学)