PTA跳转:原题链接
题目大意是:输入一个不超过20位的数字,输出该数*2后的数字,并判断该数字中每个数字的出现次数是否与原数字相同。
做题总结:不要被这个“20位”误导从而思考能否使用像"long long int"这样的类型,老老实实用字符数组做题就好,因为题目可以随时改成"100位"的。解题思路已经写在可以通过运行的源代码中了。
#include <iostream>
#include <string.h> //需要得到字符串长度
using namespace std;
int book[10];
//0~9有10个数字,记录原始数字和*2后的数字各数字出现次数之差
//如果最终所有元素都是0,则说明原数字每个数字出现的次数和*2之后相同
int main() {
char num[21]; //20位的数字,*2之后可能有21位
cin >> num;
int flag1 = 0, flag2 = 0, len = strlen(num);
for(int i = len - 1; i >= 0; i--) //和算式一样,先从最右边开始计算
{
int temp = num[i] - '0'; //比如将字符'1'变成数字1
book[temp]++; //这个位置的数字还没*2,记录+1
temp = temp * 2 + flag1; //flag是进位标志,有可能是0或1,初始状态是0
flag1 = 0;
if(temp >= 10) {
temp = temp - 10; //如果需要进位,记录下进位,为下一个位置*2做准备
flag1 = 1;
}
num[i] = (temp + '0'); //此时这个位置的数字已经是原数字*2的,如果超过10,已把十位去除保留个位
book[temp]--; //这个位置的数字已经*2,记录-1
}
for(int i = 0; i < 10; i++) {
if(book[i] != 0)
flag2 = 1; //只要book数字中有一个元素不为0,说明原数字中的这个数字和*2之后的这个数字出现次数不相同
}
//只有flag1和flag2同时为0时才会输出"Yes"
//flag1为0表示原数字最高位<5,*2后没有进位
//flag2为0表示原数字每个数字出现的次数和*2之后相同
if(flag1 == 1 || flag2 == 1)
cout << "No" << endl;
else
cout << "Yes" << endl;
if(flag1 == 1) //flag1为1表示最高位>=5,*2后有进位,最高位一定是1
cout << "1";
cout << num;
return 0;
}
氷鸢鸢鸢
2020.7.10