Have Fun with Numbers
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.
Input Specification:
Each input contains one test case. Each case contains one positive integer with no more than 20 digits.
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.
Sample Input:
1234567899
Sample Output:
Yes
2469135798
题目解析
本题给出一个长度再20以内的数字(由1~9组成),要求判断这个数字加倍后的新数字是不是这个数字的某一种排列,如果是的化输出Yes否则输出No,之后输出加倍后的数字。
由于数字最大位数为20位,超过了long long int的记录范围我们用数组num记录这个数字,用数组cnt记录num中1~9出现的次数,将num加倍后判断其中1~9出现的次数是否发送改变,若没有发送改变则证明加倍后的数字是原数字的某一种排列,反之则不是。
AC代码
1 #include <bits/stdc++.h> 2 using namespace std; 3 int num[22]; 4 int cnt[10]; 5 string str; 6 void toInt(){ 7 for(int i = 0; i < str.size(); i++) 8 num[i] = str[i] - '0'; 9 } 10 void getCnt(){ 11 for(int i = 0; i < str.size(); i++) 12 cnt[num[i]]++; 13 } 14 bool judge(int carry){ 15 if(carry != 0) //如果最高位进位不为零,则证明加倍后的数字比原数字多一位,那么其肯定不是原数字的一个排列 16 return false; 17 for(int i = 0; i < str.size(); i++) 18 cnt[num[i]]--; 19 for(int i = 1; i <= 9; i++){ //判断新的num中1~9的数量是否和加倍前一样 20 if(cnt[i] != 0) 21 return false; 22 } 23 return true; 24 } 25 int doubleNumber(){ //将数组num加倍并返回最高位进位 26 int carry = 0; 27 for(int i = str.size() - 1; i >= 0; i--){ 28 int temp = num[i]; 29 num[i] = (2 * temp + carry) % 10; 30 carry = 2 * temp / 10; 31 } 32 return carry; 33 } 34 int main() 35 { 36 cin >> str; //输入数字 37 toInt(); //将输入的数字转化为数组 38 getCnt(); //获取数组中1~9出现的次数 39 int carry = doubleNumber(); //将num加倍carry记录最高位的进位 40 if(judge(carry)){ //判断加倍后的数字是否为原数字的某一个排列 41 printf("Yes "); 42 43 }else 44 printf("No "); 45 if(carry != 0) //判断是否需要输出进位 46 printf("%d", carry); 47 for(int i = 0; i < str.size(); i++) //输出加倍后的数组num 48 printf("%d", num[i]); 49 printf(" "); 50 return 0; 51 }