PAT A1023 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 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;
}
原文地址:https://www.cnblogs.com/houzm/p/13279424.html