题目
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 diferent 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 file 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
思路
高精度乘低精度
代码
Code 01(常规解法-高精模板)
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
using namespace std;
struct bign {
int d[30];
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-1-i]-'0';
}
return a;
}
bign multi(bign a, int b) {
bign c;
int carry = 0; //进位
for(int i=0; i<a.len; i++) {
int temp = a.d[i]*b+carry;
c.d[c.len++]=temp%10;
carry = temp/10;
}
while(carry!=0) {
c.d[c.len++]=carry%10;
carry/=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;
}
void print(bign a){
for(int i=a.len-1;i>=0;i--){
printf("%d",a.d[i]);
}
}
int main(int argc,char * argv[]) {
char str[21];
scanf("%s",str);
bign strb=change(str);
bign mul = multi(strb,2);
if(judge(strb,mul))printf("Yes
");
else printf("No
");
print(mul);
return 0;
}
Code 02(优化解法)
#include <iostream>
#include <cstring>
using namespace std;
int main(int argc,char * argv[]) {
char s[22],t[30];
scanf("%s",s);
int r =0,p=0; //余数
int count[30]={0};
for(int i=strlen(s)-1; i>=0; i--) {
int temp = s[i]-'0';
count[temp]++; //统计当前位数字出现次数
int n = r+temp*2;
count[n%10]--; //统计乘结果当前位数字出现次数
t[p++]=n%10+'0'; //拼接当前计算的位到结果
r = n/10; //更新余数
}
// 处理未处理结余的余数
while(r!=0) {
count[r%10]--;
t[p++]=r%10+'0';
r=r/10;
}
// 检验是否是原数字各位数的重新排列
bool flag = true;
for(int i=0;i<strlen(s);i++){
if(count[i]!=0)flag = false;
}
if(flag)printf("Yes
");
else printf("No
");
// 打印-反序
for(int i=p-1;i>=0;i--){
printf("%c",t[i]);
}
return 0;
}