7-49 Have Fun with Numbers (20分)
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.
翻译
注意,123456789是一个9位数字,完全由1到9之间的数字组成,没有重复。把它翻倍,我们会得到246913578,它恰好是另一个9位数,包含了从1到9的数字,只是排列不同。如果我们再次加倍,看看结果如何!现在你要检查是否有更多的数字具有这个性质。也就是说,用k位数字将一个给定的数字加倍,你要判断得出的数字是否只由原数字中数字的一个排列组成。
输入说明
每个输入包含一个测试用例。每个例子包含一个不超过20位的正整数。
输出说明
对于每个测试用例,如果将输入数字加倍,得到的数字只包含原始数字的一个排列,则首先打印一行“Yes”;如果不包含,则打印“No”。然后在下一行中,打印加倍的数字。
Sample Input:
1234567899
Sample Output:
Yes
2469135798
思路
大方向是:用字符数组存储原数,如果最高位大于等于5,乘2之后肯定会进位,那就与原数数字不一样,所以用一个标记记下最高位是否需要进位的状态,再进行计算和判断,把计算后的数也存放在数组中。
判断的时候可以将前后两个数组作比较,因为输出的是乘2之后的数,可以把前后两数相同的在原数中化成另一个字母(这里我化成a),如果最后原数全部化为a且没有进位,那么这个数就符合要求。
#include <stdio.h>
#include <string.h>
#define N 21
int main (){
char start[N],end[N];
gets(start); //输入
int t,i,j,m=0,s;
int flag=0,flag1=0;
//flag标记是否有进位,flag1标记是否与原数中各数数量相等
t=strlen(start); //位数
//判断第一位大于5时进位
if((start[0]-'0')*2>=10){
end[0]='1'; //乘2只可能进一位
flag=1; //有进位,一定不等于原数
}
for(i=t-1; i>=0; i--){ //做运算
if((start[i]-'0')*2>=10){
s=(start[i]-'0')*2%10+m;
end[i+1]='0'+s;
m=1; //进位
}
else{
s=(start[i]-'0')*2+m;
end[i+1]='0'+s;
m=0; //不进位
}
}
flag1=1; //假设两数相等,找出不相等
for(i=1; i<=t; i++){ //遍历end数组
for(j=0; j<t; j++){
if(end[i]==start[j]){ //判断是否有两数相等
start[j]='a'; //若有两数相等,在start数组中变为a
break;
}
}
}
//若start数组中不全为a,则end数组中有与start数组中不相等的数
for(i=0; i<t; i++){
if(start[i]!='a'){
flag1=0; //标记该结果
break;
}
}
if(flag1==1)
printf("Yes\n");
else
printf("No\n");
if(flag==1){
for(i=0; i<=t; i++){ //有进位从第一位输出
printf("%c",end[i]);
}
}
else{
for(i=1; i<=t; i++){ //无进位从第二位输出
printf("%c",end[i]);
}
}
return 0;
}