P8115 Table 题解
其实我是别的题都不会了才做这题的
题意应该很明显了,对于每一个数,如果他用 \(16\) 进制表示会比 \(10\) 进制更短,就改成16进制。
这题主要考点是进制转换。
\(\text{Part I.}\) 进制转换
给你一个 \(10\) 进制的整数,你要怎么把它转成 \(2\) 进制?
使用短除法,把余数写出来。比如说 \(252\):
其中,左边的 \(2\) 表示除以 \(2\),右边的 \(0\) 和 \(1\) 就是二进制了。手动计算出结果之后,余数从下往上读,得到最终结果:\((252) _ {10}=(111100) _ 2\)。
16进制也是同理,就是把除以 \(2\) 改成除以 \(16\),还要注意,如果余数是两位数,就要用字母 \(A\sim F\) 代替。这里不详细讲解,得到结果是 \((252) _ {10}=(FC) _ {16}\)。
代码中省略了我们画的图,用变量存储每次的余数,最后用字符串存结果。(因为有 \(A\sim F\))
\(\text{Part II.}\) 细节
这题的输入是数组的格式,稍微复杂。
输入:用一个字符变量c来去掉多余的字符,先输入掉左大括号,接下来每次都是输入我们要转换的数和一个字符(逗号或者右大括号)。因此,我们可以这么写:
cin>>c;//输入左大括号
while(cin>>a[++n]) cin>>c;//只要他还可以输入到,就会一直输入
这样就可以得到正确的数组了。
还有一些需要注意的点:
- 大写字母的判断
- 余数倒序
- 转换成16进制的话要加"0x"
- 最后一个数后面不输出逗号,输出右大括号
- 变量类型
\(\text{Part III.}\) 代码
#include<iostream>
using namespace std;
unsigned long long a[1005];//注意类型
int n;
unsigned long long t,l=0;
int main(){
string s;
char c;//输入
cin>>c;
while(cin>>a[++n]) cin>>c;
cout<<"{";
for(int i=1;i<n;i++){//检查每个数
s="";
t=a[i];
l=0;//l是10进制下的位数
while(t) l++,t/=10;//计算位数
t=a[i];//暂时存储
while(a[i]){//转成16进制
if(a[i]%16>9) s=char(a[i]%16-10+'A')+s;
else s=char(a[i]%16+'0')+s;
a[i]/=16;
}
s="0x"+s;//加0x
if(s.size()<=l) cout<<s;//16进制更优,一定是<=
else cout<<t;//10进制更优
if(i<n-1) cout<<",";//不是最后一个,就输出逗号
}
cout<<"}"<<endl;//最后输出右大括号
return 0;
}