题目描述
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
思路
本题思路参考了柳婼小姐姐的代码。
1、将输入数字按从低位到高位的顺序按位读入,设置flag位记录每位数乘2所得进位,若相乘结果大于10则flag=1;设置book[]数组记录,每读取一位数则对应该数字的book[i]++,每得到一个乘2后的数位则对应book[i]–,如此可知符合条件的数字对应的book[i]=0。
2、设置flag1检查book数组中是否有非0元素存在,即判定输入的数字是否符合条件。
代码
代码1:
#include <cstdio>
#include <string.h>
using namespace std;
int main()
{
char s[20];
scanf("%s",s);
int len=strlen(s),flag=0,book[10]={0};
for(int i=len-1;i>=0;i--){
int t=s[i]-'0';
book[t]++;
t=t*2+flag;
flag=0;
if(t>=10){
t=t-10;
flag=1;
}
s[i]=t+'0';
book[t]--;
}
int flag1=0;
for(int i=0;i<10;i++){
if(book[i]!=0) flag1=1;
}
if(flag==0&&flag1==0) printf("Yes\n");
else printf("No\n");
if(flag==1) printf("1");
printf("%s",s);
}
代码2:
#include <cstdio>
#include <string.h>
#include <iostream>
using namespace std;
struct bign{
int d[25];
int len;
bign(){
memset(d,0,sizeof(d));
len=0;
}
};
bign change(char str[]){
bign a;
a.len=strlen(str);
for(int i=0;i<a.len;i++){
a.d[i]=str[a.len-i-1]-'0';
}
return a;
}
bign multi(bign a,int b)
{
bign c;
int flag=0,temp=0;
for(int i=0;i<a.len;i++){
int temp=a.d[i]*b+flag;
c.d[c.len++]=temp%10;
flag=temp/10;
//printf("%d ",c.d[c.len-1]);
}
while(flag!=0){
c.d[c.len++]=flag%10;
flag/=10;
}
return c;
}
bool judge(bign a,bign b){
if(a.len!=b.len) return false;
int count[10]={0};
for(int i=0;i<a.len;i++){
count[a.d[i]]++;
count[b.d[i]]--;
}
for(int i=0;i<10;i++){
if(count[i]!=0) return false;
}
return true;
}
int main()
{
char str[25];
cin.getline(str,25);
bign a=change(str);
bign mul=multi(a,2);
bool res=judge(a,mul);
if(res==true) printf("Yes\n");
else printf("No\n");
for(int i=mul.len-1;i>=0;i--){
printf("%d",mul.d[i]);
}
}
备注
1、本题最开始的思路是采用如下的方式进行乘2运算,但是代码过程中出现问题,有时间再试试。
if(i==len-1) str2[i]=((str1[i]-'0')*2%10)+'0';
else if(i==0) str2[i]=((str1[i]-'0')*2+(str1[i+1]-'0')*2/10)+'0';
else str2[i]=((str1[i+1]-'0')*2/10+(str1[i]-'0')*2%10)+'0';
2、晴神的思路是创建结构体,将字符串转换为包含int型数组的结构体,字符串中的数字存放在结构体的int数组中,之后对Int数组进行乘法和比较操作。(代码2)
3、PAT中的编译不支持使用gets()函数,输入字符串时可以使用cin.getlin()函数或scanf进行输入。