【蓝桥杯】算法训练 进制转换

问题描述
  我们可以用这样的方式来表示一个十进制数: 将每个阿拉伯数字乘以一个以该数字所处位置的(值减1)为指数,以10为底数的幂之和的形式。例如:123可表示为 1*102+2*101+3*100这样的形式。
  与之相似的,对二进制数来说,也可表示成每个二进制数码乘以一个以该数字所处位置的(值-1)为指数,以2为底数的幂之和的形式。一般说来,任何一个正整数 R R R或一个负整数 - R -R 都可以被选来作为一个数制系统的基数。如果是以 R R - R -R 为基数,则需要用到的数码为 0 , 1 , . . . . R - 1 0,1,....R-1 。例如,当 R = 7 R=7 时,所需用到的数码是 0 , 1 , 2 , 3 , 4 , 5 和 6 0,1,2,3,4,5和6 ,这与其是 R 或 - R R或-R 无关。如果作为基数的数绝对值超过10,则为了表示这些数码,通常使用英文字母来表示那些大于9的数码。例如对16进制数来说,用 A A 表示10,用 B B 表示11,用 C C 表示12,用 D D 表示13,用 E E 表示14,用 F F 表示15。
  在负进制数中是用 - R -R 作为基数,例如-15(十进制)相当于110001(-2进制),并且它可以被表示为2的幂级数的和数:
  110001=1*(-2)5+1*(-2)4+0*(-2)3+0*(-2)2+
  0*(-2)1 +1*(-2)0
   设计一个程序,读入一个十进制数和一个负进制数的基数, 并将此十进制数转换为此负进制下的数: - R -R ∈{-2,-3,-4,...,-20}
输入格式
  一行两个数,第一个是十进制数 N N (-32768<= N N <=32767), 第二个是负进制数的基数 - R -R
输出格式
  输出所求负进制数及其基数,若此基数超过10,则参照16进制的方式处理。(格式参照样例)
样例输入1
30000 -2
样例输出
30000=11011010101110000( b a s e − 2 base-2 base2)
样例输入
-20000 -2
样例输出
-20000=1111011000100000( b a s e − 2 base-2 base2)
样例输入
28800 -16
样例输出
28800=19180( b a s e − 16 base-16 base16)
样例输入
-25000 -16
样例输出
-25000=7 F B 8 FB8 FB8( b a s e − 16 base-16 base16)

个人思路:主要考察对负数求余的处理。一个数求余另一个数得到一个负数,必然被除数为负数(此时商与除数异号),这个时候可以根据“被除数 = 除数 * 商 + 余数”来进行处理,要想余数得到正数,则我们可以让商加1,则余数等于"被除数 - 除数 * 商”,余数就可以得到正数

7 % (-3) = -2 …1
(-7) % 3 = -2…-1
(-7) % (-3) = 2…-1

#include 
#include 
using namespace std;
int n, m; 
char a[20];
int main(int argc, char** argv) {
	cin >> n >> m;
	cout << n << "=";
	int i = 0;
	while (n) {
		int temp = n % m;
		int t1 = n;
		n /= m;
		//为负数,则商先加1再取余 
		//除数*商 + 余数 = 被除数 
		if (temp < 0) {
			while (temp < 0) {
				n++;
				temp = t1 - n * m;
			}
		}
		if (temp < 10) {
			a[i++] = temp + '0';
		}
		else
			a[i++] = temp + 'A' - 10;
	}
	for (int j = i - 1; j >= 0; --j) {
		cout << a[j];
	}
	cout << "(base" << m << ")" << endl;
	return 0;
}

你可能感兴趣的:(【蓝桥杯】)