题目描述:
样例说明:
C++代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define x first
#define y second
typedef pair<int, int> node;
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int get_sum(int x)
{
int sum = 0;
do {
sum += x % 10;
x /= 10;
} while (x > 0);
return sum;
}
bool is_prime(int x)
{
if (x <= 2) return false;
for (int i = 2; i <= x / i; i++) if (x % i == 0) return false;
return true;
}
void dfs(int u, int j, int cur, int k, int m, int curm, vector<node>& res)
{
if (u > k - j)
{
int plus = 1;
for (int i = 0; i < j; i++) plus *= 10; // 注意:尽量不要使用pow函数,很慢
int w = cur * plus + (plus - 1);
if (get_sum(w) != m) return;
int n = get_sum(w + 1);
if (is_prime(gcd(m, n))) res.push_back({ n, w });
return;
}
for (int i = 0; i <= 9; i++)
{
if (curm + i > m) return; // 可行性剪枝:如果下一步超过m,则后面都会超过m
if (u == 1 && i == 0) continue; // 根据题意:第一个位置不能为0,因为是k位数
if (u + 1 > k - j && i == 9) return; // 排除等效冗余剪枝:如果后j为都为9,则后j + 1位不能为9,否则在第j位的时候已经算过了
dfs(u + 1, j, cur * 10 + i, k, m, curm + i, res);
}
}
int main()
{
int t;
scanf("%d", &t);
for (int i = 1; i <= t; i++)
{
int k, m;
scanf("%d%d", &k, &m);
printf("Case %d\n", i);
if (m > k * 9)
{
puts("No Solution");
continue;
}
vector<node> res;
for (int j = k; j >= 1; j--) // j为最后连续9的个数
{
if (j * 9 > m) continue; // 可行性剪枝:如果后j位的9的和已经大于m了,那么可以直接去掉
dfs(1, j, 0, k, m, 0, res);
}
if (res.empty())
{
puts("No Solution");
continue;
}
for (int j = 0; j < res.size(); j++) printf("%d %d\n", res[j].x, res[j].y);
}
return 0;
}