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;//只要他还可以输入到,就会一直输入

这样就可以得到正确的数组了。

还有一些需要注意的点:

  1. 大写字母的判断
  2. 余数倒序
  3. 转换成16进制的话要加"0x"
  4. 最后一个数后面不输出逗号,输出右大括号
  5. 变量类型

\(\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;
}
posted @ 2022-02-07 18:56  cyx001  阅读(41)  评论(0编辑  收藏  举报