洛谷P8115Table 题解

P8115 Table 题解

Part.1 题目

题目传送门

怎么能打表呢?

题目让我们帮助小a打表 (???) ,如果加上 0x 之后的 $16$ 进制更短,就换成 $16$ 进制再输出,否则保持原样。

Part.2 思路

因为 $a_i \leq 2^{64}$ ,所以要开 unsigned long long ,输入输出时也要用 %llu

先把 $10$ 进制长度、 $16$ 进制长度都算出来,如果 $16$ 进制更短,就把 $16$ 进制一位一位算出来(记得要加上 0x ),但是要记住 $10$ 要变成 A ,$11$ 要变成 B

最后要特判,如果是空数组也要输出空数组

Part.3 代码

#include<cstdio>
using namespace std;
typedef unsigned long long ull;//这样就不用每次都打一遍unsigned long long 了
ull a[1024];
int main(){
	char x;int n=0;
	while(1){
		scanf("%c",&x);
		if(x=='}')break;
		scanf("%llu",&a[n++]);
	}//输入,因为是字符('}',',')和数字交替出现,所以可以这样
	printf("{");//先把开头的大括号输出好
	if(n==1&&a[0]==0){printf("}");return 0;}//特判,如果是空数组就要输出空数组
	for(int i=0;i<n;i++){
		ull ai=a[i];
		int len_dec=0,len_hex=0;
		for(;ai;len_dec++)ai/=10;//算10进制位数
		ai=a[i];
		for(;ai;len_hex++)ai/=16;//算16进制位数
		if(len_dec<len_hex+2)printf("%llu",a[i]);//因为前面要加上0x,所以要加2
		else{
			printf("0x");//先输出0x
			ai=a[i];len_hex--;
			for(;len_hex>=0;len_hex--){
				int x=ai>>(len_hex*4);//极简位运算,相当于x=ai/pow(16,len_hex)
				printf("%c",x>9?x+55:x+48);//达到10要变成字母,A的ASCII码是65,0的ASCII码是48
				ai%=(1ull<<(len_hex*4));//还是位运算,把前面4位二进制去掉
			}
		}
		if(i==n-1)printf("}");//如果已经是最后一个数了,就直接输出'}'结束,不再输出','了
		else printf(",");
	}
}