PAT 1160 Forever

个人学习记录,代码难免不尽人意。

“Forever number” is a positive integer A with K digits, satisfying the following constrains:

the sum of all the digits of A is m;
the sum of all the digits of A+1 is n; and
the greatest common divisor of m and n is a prime number which is greater than 2.
Now you are supposed to find these forever numbers.

Input Specification:
Each input file contains one test case. For each test case, the first line contains a positive integer N (≤5). Then N lines follow, each gives a pair of K (3

Output Specification:
For each pair of K and m, first print in a line Case X, where X is the case index (starts from 1). Then print n and A in the following line. The numbers must be separated by a space. If the solution is not unique, output in the ascending order of n. If still not unique, output in the ascending order of A. If there is no solution, output No Solution.

Sample Input:
2
6 45
7 80
Sample Output:
Case 1
10 189999
10 279999
10 369999
10 459999
10 549999
10 639999
10 729999
10 819999
10 909999
Case 2
No Solution

#include
using namespace std;

int N, K, m;
vector<vector<int>> ans;

bool IsPrime(int num) {
	if (num <= 2) return false;
	for (int i = 2; i * i <= num; i++) {
		if (num % i == 0) return false;
	}
	return true;
}

int gcd(int a, int b) {
	return b ? gcd(b, a % b) : a;
}

int Sum(int num) {
	int sum = 0;
	while (num > 0) {
		sum += num % 10;
		num /= 10;
	}
	return sum;
}

bool Solution() {
	ans.clear();
	ans.resize(100);
	int cnt = 0;
	if (K * 9 < m) return false;//剪枝(加不加都能过)
	int start = pow(10, K - 1);
	for (int i = start + 9; i < start * 10; i += 10) {
		if (Sum(i) == m) {
			int n = Sum(i + 1);
			if (IsPrime(gcd(m, n))) {
				ans[n].push_back(i);
				cnt++;
			}
		}
	}
	return (cnt > 0);
}

int main() {
	scanf("%d", &N);
	for (int i = 1; i <= N; i++) {
		scanf("%d%d", &K, &m);
		printf("Case %d\n", i);
		if (Solution()) {
			for (int j = 0; j < ans.size(); j++)
				if(ans[j].size() != 0)
					for(int k = 0; k < ans[j].size(); k++)
						printf("%d %d\n", j, ans[j][k]);
		}
		else
			printf("No Solution\n");
	}

	return 0;
}

这道题代码抄的别人的,选了一个简单的能看懂的。汗
我自己做的时候暴力硬做的,结果最后两个测试点一个超时一个答案错误,为了节约时间就没继续看,但是因为这道题应该是某年PAT考试的第一题所以我感觉不会特别难。
这道题能满分做出来的关键在于能不能看出符合要求的数都是以9结尾的,如果能看出来的话就可以节约很多时间。怎么看出来呢?其实也很简单,题目要求A和A+1的按位相加结果m和n必须有大于2的素数最大公因数,因此如果A的结尾不是9的话,m和n的大小也应该是n=m+1,所以n和m的最大公因数不可能是2以上的素数,所以结尾必须是9!是9之后加1就可以进位!

如果遇到很麻烦的题,时间不够可以先暴力求解得到一部分的分数,然后可以考虑能不能发现其中所在的数学规律或者结构规律来做。

你可能感兴趣的:(PTA,算法,c++,pat,数据结构)