PAT (Advanced Level) Practice 1023 Have Fun with Numbers (20 分) 凌宸1642

时间:2021-04-18 04:53:45

PAT (Advanced Level) Practice 1023 Have Fun with Numbers (20 分) 凌宸1642

题目描述:

Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, with no duplication. Double it we will obtain 246913578, which happens to be another 9-digit number consisting exactly the numbers from 1 to 9, only in a different permutation. Check to see the result if we double it again!

Now you are suppose to check if there are more numbers with this property. That is, double a given number with k digits, you are to tell if the resulting number consists of only a permutation of the digits in the original number.

译: 注意到数字 123456789 是一个恰好由数字 1 到 9 组成的没有重复数字的 9 位数。将它翻倍我们将会得到 246913578 , 刚好也是一个由数字 1 到 9 组成的没有重复数字的 9 位数的一个不同排列。如果我们再翻一倍看看结果如何!

现在你要检查是否更多的数字具有这个性质。给定一个 k 位数,将其翻倍,你应该告诉这个结果的数字是否是由原先数字的不同的排列组成。


Input Specification (输入说明):

Each input contains one test case. Each case contains one positive integer with no more than 20 digits.

译:每个输入文件包含一个测试用例,每个用例包含一个不超过 20 位的正整数。


Output Specification (输出说明):

For each test case, first print in a line "Yes" if doubling the input number gives a number that consists of only a permutation of the digits in the original number, or "No" if not. Then in the next line, print the doubled number.

译:对于每个测试用例,如果将输入的数字翻倍后的结果是由原先数字的一个不同排列,在第一行中输出 Yes ,否则输出 No 。在接下来的一行中,输出翻倍后的数字。


Sample Input (样例输入):

1234567899

Sample Output (样例输出):

Yes
2469135798

The Idea:

设计到大整数(超过 long long 范围)的运算,虽然只是一个简单的翻倍,所以需要用数组来存储输入数据,为了在输出时更方便,我选择了直接使用 string 类型存储输入数据和输出结果。

对于大整数的加倍,从最后一位开始,将每一位数翻倍,对应位置上的结果如果大于等于 10 ,则进位。

对于比较两者是否是一个同一群数字的不同排列,我又偷懒的选择了利用 map ,直接统计每个数字出现的次数,如果每个数字出现的次数都相同,那么显然是同一个排列。


The Codes:

#include<bits/stdc++.h>
using namespace std;
map<char , int > mp1 , mp2;
int main(){
string s , ans = "";
cin >> s ;
int temp , flag = 0 ;
for(int i = s.size() - 1 ; i >= 0 ; i --){
mp1[s[i]] ++ ; // 记录输入数字的每个数字出现的次数
temp = (s[i] - '0') * 2 + flag ; // 计算该位置上每位数的翻倍结果,加上低位来的进位
ans += to_string(temp % 10) ; // 拼接到结果中
flag = temp / 10 ; // 重新计算 进位
}
if(flag) ans += to_string(flag) ;
for(int i = ans.size() -1 ; i >= 0 ; i --) mp2[ans[i]] ++ ; // 记录结果的每个数字出现的次数
printf((mp1 == mp2)?"Yes\n":"No\n"); // 判断是否是同样数字的不同排列
reverse(ans.begin() , ans.end()) ; // ans 倒置才是翻倍结果
cout<< ans <<endl;
return 0;
}