题目大意:
给出一个长度不超过20的整数,问这个整数两倍后的数位是否为原数位的一个排列
思路:
参考[算法笔记]大整数运算
1)以大整数方式读入数字,并进行乘法运算,将其乘2。
2)判断新整数是否为原整数的一个排列。
1.如果两个整数的长度不相等,那么就一定不成立。
2.如果两个整数的长度相等,定义count数组,用来存放0-9中每个数字出现的个数,枚举两个整数所有数位,对于原整数中所有值,令对应count值加1,
新整数中所有值,令对应count值减一。最后如果count数组每一项都为0,返回true,否则返回false。
3)输出。无论是Yes还是No,都要输出乘2后的新整数。
AC代码:
//PAT_A 1023
#include<cstdio>
#include<cstring>
using namespace std;
struct bign {
int d[21];
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 < a.len; 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() {
char str[21];
(void)scanf("%s", str);
bign a = change(str);
bign num = multi(a, 2);
if (Judge(a, num) == true)printf("Yes\n");
else printf("No\n");
print(num);
return 0;
}