这个题我看2000ms直接暴力枚举了,有一个测试点过不去,不知道原因。
大概思路就是最后两位时99,那么k - 2位。第一位一定是(1 ~ 9)所以就从10。。。(k - 3个零,到10.。。。(k - 2个零)例子1就是100099到999999,满足条件的就存入再排序。
#include <bits/stdc++.h>
using namespace std;
struct node {
string s;
int n;
};
bool isPrime (int n) {
if (n <= 2) return false;
for (int i = 2; i <= sqrt(n); i++) {
if (n % i == 0) return false;
}
return true;
}
int gcd (int a, int b) {
return a % b == 0 ? b : gcd (b, a % b);
}
int sum (string s) {
int sum = 0;
for (int i = 0; i < s.size(); i++) sum += s[i] - '0';
return sum;
}
bool cmp (node a, node b) {
if (a.n != b.n) return a.n < b.n;
return a.s < b.s;
}
vector<node> ans;
int main() {
string s;
int n, m, a, k, rem;
scanf ("%d", &n);
for (int i = 0; i < n; i++) {
printf ("Case %d\n", i + 1);
ans.clear();
scanf ("%d %d", &k, &m);
if (m >= k * 9 || m <= 18) { //感觉小于27都不行
printf ("No Solution\n");
continue;
}
s = "99";
rem = m - 2 * 9;
string temp, aft;
for (int j = (int)pow(10, k - 3); j < (int)pow(10, k - 2); j++) {
int now = j + 1;
temp = to_string(j);
if (sum(temp) == rem) {
aft = to_string(now);
int sumN = sum(aft);
int maxD = gcd (sumN, m);
if (isPrime (maxD)) {
ans.push_back(node {temp + s, sumN});
}
}
}
if (ans.size() == 0) printf ("No Solution\n");
for (int j = 0; j < ans.size(); j++) {
printf ("%d %s\n", ans[j].n, ans[j].s.c_str());
}
}
}