原题链接:https://www.luogu.com.cn/problem/P1017
题意解读:负进制数的转换。
解题思路:
下面给出两种思路
1、枚举法
从数据范围来看,∣n∣ ≤ 37336,因此,可以对该r进制的数进行枚举,每一次枚举,都计算r进制数对应的十进制数是否和n相等,相等则输出该r进制数。
主要问题就是要解决r进制数如何表示?
类似于高精度,可以用数组来表示一个r进制数,如二进制1101表示为int a[] = {1, 0, 1, 1}
枚举起始时,a[] = {0},每一次最低位+1,a[0]++,如果a[0] = |r|,处理进位。
100分代码:
#include <bits/stdc++.h>
using namespace std;
int a[100], cnt = 1;
int n, r;
//将r进制的a[]转换为十进制数
int trans()
{
int res = 0;
for(int i = cnt - 1; i >= 0; i--)
{
res = res * r + a[i];
}
return res;
}
char getchar(int x)
{
char res = '0';
if(x >= 0 && x <= 9) res = x + '0';
if(x >= 10) res = x - 10 + 'A';
return res;
}
int main()
{
cin >> n >> r;
int R = -r; //r是负数,R = abs(r)
while(n != trans()) //如果r进制数a转换十进制后不等于n
{
int d = 1;
for(int i = 0; i < cnt; i++) //给r进制数a加1
{
a[i] += d;
d = a[i] / R;
a[i] %= R;
}
if(d) a[cnt++] = d;
}
cout << n << "=";
for(int i = cnt - 1; i >= 0; i--) cout << getchar(a[i]);
cout << "(base" << r << ")";
return 0;
}
2、除留余数法
能不能基于进制转换的标准算法来做呢,
例如:-15转-2进制的过程,理论上应该是这样的:
-15 ➗ -2 = 8 ...... 1
8 ➗ -2 = -4 ...... 0
-4 ➗ -2 = 2 ...... 0
2 ➗ -2 = -1 ...... 0
-1 ➗ -2 = 1 ...... 1
1
逆序输出就是110001
但实际上,在C++中,计算结果是这样的
-15 ➗ -2 = 7 ...... -1
8 ➗ -2 = -4 ...... 0
-4 ➗ -2 = 2 ...... 0
2 ➗ -2 = -1 ...... 0
-1 ➗ -2 = 0 ...... -1
可以看到,当负数除以负数时,余数是负数,而我们要求余数必须为正,就可以通过给余数增加|r|来修正
既然余数增加了|r|,对应商就应该加1,通过如此修正就得到了手工计算一样的结果。
100分代码:
#include <bits/stdc++.h>
using namespace std;
int n, r;
char getchar(int x)
{
char res = '0';
if(x >= 0 && x <= 9) res = x + '0';
if(x >= 10) res = x - 10 + 'A';
return res;
}
int main()
{
cin >> n >> r;
int nn = n, rr; //nn商,rr余数
vector<int> ans;
while(nn)
{
rr = nn % r;
nn /= r;
if(rr < 0) //余数小于0
{
rr -= r; //余数加|r|
nn++; //商加1
}
ans.push_back(rr);
}
cout << n << "=";
for(int i = ans.size() - 1; i >= 0; i--) cout << getchar(ans[i]);
cout << "(base" << r << ")";
return 0;
}
标签:NOIP2000,进制,rr,int,洛谷题,P1017,res,余数,...... From: https://www.cnblogs.com/jcwy/p/18119143