【题目】
https://www.luogu.org/problem/P1017
标签:数学、进制
【思路】
求进制数很容易想到用输入数据一直对要转换的进制基数取余数,再倒序输出即可。
问题在于:因为是负进制数,在C++中,-15/-2=7,而-15%-2=-1,所以会出现余数为负数的情况。
先说结论,对于余数为负数,可以通过 余数-除数(进制数基数),商+1 来解决。余数绝对值肯定小于除数绝对值,且都为负数,余数减除数就变为正数了。
说明,举个栗子:
对于52的-4进制数为 (3 -1 0),计算 3 ∗ ( − 4 ) 2 + ( − 1 ) ∗ ( − 4 ) 1 = 48 + 4 = 52 3*(-4)^2+(-1)*(-4)^1 = 48 + 4 = 52 3∗(−4)2+(−1)∗(−4)1=48+4=52 。
用-1减去进制数基数-4得到3,高一位加1,变成 (4 3 0),计算 4 ∗ ( − 4 ) 2 + 3 ∗ ( − 4 ) 1 = 64 − 12 = 52 4*(-4)^2 + 3*(-4)^1 = 64 - 12 = 52 4∗(−4)2+3∗(−4)1=64−12=52 。
原理是52的-4进制数 (3 -1 0) 中的-1是乘于进制数基数-4,得到结果是正数4。而转换为3后乘于进制数基数-4,该位的结果是-12。高一位加1,增加了 1 ∗ ( − 4 ) 2 = 16 1*(-4)^2 = 16 1∗(−4)2=16,然后16-12结果还是原来的4。
【代码】
#include <iostream>
#include <stack>
using namespace std;
int main() {
int n, r;
cin >> n >> r;
stack<char> st;
int t = n;
// 进制转换
while (t != 0) {
int m = t%r;
t /= r;
if (m < 0) { // 处理余数小于0
m -= r;
t++;
}
if (m >= 10) { // 处理基数绝对值大于等于10
st.push(m - 10 + 'A');
}
else {
st.push(m + '0');
}
}
// 输出
cout << n << "=";
while (!st.empty()) {
cout << st.top();
st.pop();
}
cout << "(base" << r << ")" << endl;
return 0;
}