题目分析
因为数字长度K不超过10,可以考虑采用dfs+剪枝
代码
#include <iostream>
#include<vector>
#include<map>
using namespace std;
int N, K, m;
vector<vector<int>> res;
vector<int> tmp;
bool is_prime(int n) {
if (n <= 2) {
return false;
}
for (int i = 2; i*i<=n; i++) {
if (n%i==0) {
return false;
}
}
return true;
}
//辗转相除法
int gcd(int a, int b) {
int r;
if (a < b) {
r = a;
a = b;
b = r;
}
return b==0?a:gcd(b,a%b);
}
int get_digit_sum(int n) {
int r = 0;
while (n != 0) {
r += (n % 10);
n /= 10;
}
return r;
}
int to_int(vector<int> v) {
int r = 0;
for (int i = 0; i < v.size(); i++) {
r =10*r+v[i];
}
return r;
}
//dfs+剪枝
void dfs(int K,int tsum) {
//剩余的数全为9也无法计算得到sum
if (K*9< tsum) {
return;
}
if (K==0&& tsum == 0) {
res.push_back(tmp);
return;
}
//已经加入答案的数字如果已经大于需要的综合也需要剪枝
int cnt = 0;
for (int i = 0; i < tmp.size(); i++) {
cnt += tmp[i];
}
if (cnt > m) return;
for (int i = 0; i <= 9; i++) {
tmp.push_back(i);
dfs(K-1,tsum-i);
tmp.pop_back();
}
}
int main()
{
cin >> N;
for (int i = 0; i < N; i++) {
cin >> K >> m;
cout << "Case " << i + 1 << endl;
if (m >= K * 9) {
printf("No Solution\n");
continue;
}
map<int, vector<int>> Ma;
for (int i = 1; i <= 9; i++) {
res.clear();
tmp.clear();
tmp.push_back(i);
dfs(K-1,m-i);
//此时计算了一组tmp
for (int j = 0; j < res.size(); j++) {
int t = to_int(res[j]);
int nsum = get_digit_sum(t+1);
//cout<<"nsum="<<nsum << ",gcd=" << t1 << ",is_prime" << t2 << endl;
if (is_prime(gcd(m,nsum))) {
Ma[nsum].push_back(t);
}
}
}
if (Ma.size() == 0) {
cout << "No Solution" << endl;
}
else {
//排序
for (auto it = Ma.begin(); it != Ma.end(); it++) {
for (int j = 0; j < it->second.size(); j++) {
cout << it->first << " " << it->second[j] << endl;
}
}
}
}
}