1104 天长地久——20分

“天长地久数”是指一个 K 位正整数 A,其满足条件为:A 的各位数字之和为 m,A+1 的各位数字之和为 n,且 m 与 n 的最大公约数是一个大于 2 的素数。本题就请你找出这些天长地久数。

输入格式:
输入在第一行给出正整数 N(≤5),随后 N 行,每行给出一对 K(3<K<10)和 m(1<m<90),其含义如题面所述。

输出格式:
对每一对输入的 K 和 m,首先在一行中输出 Case X,其中 X 是输出的编号(从 1 开始);然后一行输出对应的 n 和 A,数字间以空格分隔。如果解不唯一,则每组解占一行,按 n 的递增序输出;若仍不唯一,则按 A 的递增序输出。若解不存在,则在一行中输出 No Solution

输入样例:

2
6 45
7 80

输出样例:

Case 1
10 189999
10 279999
10 369999
10 459999
10 549999
10 639999
10 729999
10 819999
10 909999
Case 2
No Solution

|代码长度限制 | 时间限制 | 内存限制 |
| 16KB | 3000ms | 64MB |

思路一(字符串转换):
先写好判断素数和计算最大公约数的函数,根据输入确定范围,将范围内的每个数都转成字符串计算出每一位数字之和是否满足条件,满足则输出,如果范围内满足条件数不存在,输出No Solution,但是因为C++的数字计算并非采用字符串类型,因此当数字较大时进行大量计算会使程序的时间复杂度大增,所以此种写法后面两个测试点会超时,20分只能通过12分

代码:

#include<bits/stdtr1c++.h>
using namespace std;
int isPrime(int n) {
	if (n < 2) return 0;
	for (int i = 2; i * i <= n; i++) {
		if (n % i == 0)
			return 0;
	}
	return 1;
}
int gcd(int a, int b) {
	return !b ? a : gcd(b, a % b);
}
int main() {
	int N;
	cin >> N;
	int K, m;
	for (int i = 1; i <= N; i++) {
		cin >> K >> m;
		printf("Case %d\n", i);
		int flag = 0;
		for (long long int j = int(pow(10, K - 1)); j < int(pow(10, K)); j++) {
			string A1 = to_string(j), A2 = to_string(j + 1);
			int sum1 = 0, sum2 = 0;
			for (auto c : A1) sum1 += c - '0';
			for (auto c : A2) sum2 += c - '0';
			if (sum1 != m) continue;
			else if (sum1 == m && isPrime(gcd(sum1, sum2)) && gcd(sum1, sum2) > 2) {
				flag = 1;
				cout << sum2 << " " << A1 << endl;
			}
		}
		if (!flag) cout << "No Solution" << endl;
	}
	return 0;
}

思路二(可以全部通过的思路):正在努力思考中(ó﹏ò。)
2022.9.30更新:经过不懈的努力,终于拿下了,20分可以全部通过

代码:

#include<bits/stdtr1c++.h>
using namespace std;
struct node {
    int n, num;
    friend bool operator < (node &a, node &b) {
        if (a.n != b.n) return a.n < b.n;
        return a.num < b.num;
    }
} T;
int N, K, m, temp, sum, sum2, I, II;
vector<node> A;
int is_prime(int x) {
    if (x <= 2) return 0;
    for (int i = 2; i <= sqrt(x); i++) {
        if (x % i == 0) return 0;
    }
    return 1;
}
int main() {
    cin >> N;
    for (int i = 1 ; i <= N; i++) {
        A.clear();
        cout << "Case " << i << '\n';
        cin >> K >> m;
        if (K * 9 < m) cout << "No Solution\n";
        else {
            temp = pow(10, K - 2);
            for (int i = temp / 10; i < temp; i++) {
                sum = 18, sum2 = 0, I = i, II = i + 1;
                while (I) {
                    sum += I % 10;
                    I /= 10;
                    if (sum > m) break;
                }
                while (II) {
                    sum2 += II % 10;
                    II /= 10;
                }
                if (sum == m && is_prime(__gcd(m, sum2))) {
                    T.n = sum2, T.num = i;
                    A.push_back(T);
                }
            }
            sort(A.begin(), A.end());
            if (A.empty()) cout << "No Solution\n";
            for (auto &it : A) {
                cout << it.n << ' ' << it.num << "99\n";
            }
        }
    }
    return 0;
}
posted @ 2022-09-12 23:03  Fare-Well  阅读(80)  评论(0)    收藏  举报