【题目链接】
ybt 1820:【00NOIP提高组】进制转换
洛谷 P1017 [NOIP2000 提高组] 进制转换
注意:两OJ上题目内容相同,输入输出要求不同
【题目考点】
1.数制
【解题思路】
在题目描述下,对负数r进制数字n,各位为
d
n
d
n
−
1
.
.
.
d
1
d
0
d_nd_{n-1}...d_1d_0
dndn−1...d1d0,按位权展开为:
n
=
d
n
∗
r
n
+
d
n
−
1
∗
r
n
−
1
+
.
.
.
+
d
1
∗
r
1
+
d
0
∗
r
0
n = d_n*r^n+d_{n-1}*r^{n-1}+...+d_1*r^1+d_0*r^0
n=dn∗rn+dn−1∗rn−1+...+d1∗r1+d0∗r0
其中
d
0
,
d
1
,
.
.
.
,
d
n
d_0,d_1,...,d_n
d0,d1,...,dn必须都为正数
除去最后一项,其余项加和一定是r的倍数:
d
n
∗
r
n
+
d
n
−
1
∗
r
n
−
1
+
.
.
.
+
d
1
∗
r
1
=
r
⋅
(
d
n
∗
r
n
−
1
+
d
n
−
1
∗
r
n
−
2
+
.
.
.
+
d
1
∗
r
0
)
d_n*r^n+d_{n-1}*r^{n-1}+...+d_1*r^1 = r\cdot (d_n*r^{n-1}+d_{n-1}*r^{n-2}+...+d_1*r^0)
dn∗rn+dn−1∗rn−1+...+d1∗r1=r⋅(dn∗rn−1+dn−1∗rn−2+...+d1∗r0),简记为
r
⋅
q
r\cdot q
r⋅q
即
n
=
r
⋅
q
+
d
0
⇒
n
−
d
0
=
r
⋅
q
n = r\cdot q + d_0 \Rightarrow n-d_0 = r\cdot q
n=r⋅q+d0⇒n−d0=r⋅q
其中
0
≤
d
0
<
∣
r
∣
0\le d_0<|r|
0≤d0<∣r∣
n需要减一个正数
d
0
d_0
d0,使其是r的整数倍。
d
0
d_0
d0即为r在可能为负数情况下广义的“n对r取模”的值。该值无法在c++中通过n%r
得到。
使用该方法求两个整数取模的值,在运算数是正数、负数条件下都适用,写成函数为:
int mod(int a, int b)//求a对b取模的值,在a,b为负数条件下依然适用
{
for(int r = 0; r < abs(b); ++r)
{
if((a-r)%b == 0)
return r;
}
}
用该函数求
d
0
d_0
d0的值,记录在数组中。
而后计算
n
=
(
n
−
d
0
)
/
r
n=(n-d_0)/r
n=(n−d0)/r,再用同样的方法求出下一个数位
d
1
d_1
d1。
如此循环,直到n为0。
最后输出记录的各位数字。输出时,注意将10以上的数字转为字母。
【题解代码】
ybt 1820:【00NOIP提高组】进制转换
注意处理多组数据,要做状态还原
#include<bits/stdc++.h>
using namespace std;
int num[50], ni;
int mod(int a, int b)
{
for(int r = 0; r < abs(b); ++r)
{
if((a-r)%b == 0)
return r;
}
}
int main()
{
int n, r, a, m;
while(cin >> n >> r)//r:基数
{
ni = 0;//状态还原
a = n;
do//用do...while,即便a为0,也会填充到数组中
{
m = mod(a, r);//"取模"结果
num[++ni] = m;//将余数填充到数组中
a = (a - m) / r;
}while(a != 0);
for(int i = ni; i >= 1; --i)//高位到低位输出数字
cout << (num[i] < 10 ? char(num[i]+'0') : char(num[i]-10+'A'));//若超过10,转为16进制输出
cout << endl;
}
return 0;
}
洛谷 P1017 [NOIP2000 提高组] 进制转换
#include<bits/stdc++.h>
using namespace std;
int num[50], ni;
int mod(int a, int b)
{
for(int r = 0; r < abs(b); ++r)
{
if((a-r)%b == 0)
return r;
}
}
int main()
{
int n, r, a, m;
cin >> n >> r;//r:基数
a = n;
do//用do...while,即便a为0,也会填充到数组中
{
m = mod(a, r);
num[++ni] = m;//将余数填充到数组中
a = (a - m) / r;
}while(a != 0);
cout << n << '=';
for(int i = ni; i >= 1; --i)//高位到低位输出数字
cout << (num[i] < 10 ? char(num[i]+'0') : char(num[i]-10+'A'));//若超过10,转为16进制输出
cout << "(base" << r << ")";
return 0;
}