题意理解
dfs
我的想法是,这显然是个组合数,最糟糕的情况是 (2010)=184756 ,对于组合数,肯定是用深搜回溯。
素数
然后数的和加起来不会超过 10∗5000000=50000000
所以我就想要不要把预处理出50000000以内的所有的素数,然后直接打表去判断是否是素数。当然这个做法我全都TLE了。。。
于是想着,反正算素数复杂度也就是 O(n−−√) ,然后就对每个素数进行判断吧。
其他
我在跑完了代码之后,觉得数据应该挺小的。。。。。。哪怕少点优化应该也可以过。
代码
#include <cstring>
#include <iostream>
#include <cmath>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iomanip>
#include <vector>
using namespace std;
bool is_prime(int num) {
if(num == 2 || num == 3) {
return true;
}
if(num % 6 != 1 && num % 6 != 5) {
return false;
}
int tmp = sqrt(num) + 1;
for(int i= 5;i <= tmp; i += 6) {
if(num % i == 0 || num % (i+ 2) == 0) {
return false;
}
}
return true;
}
void read(int &x) {
x = 0;
int f = 1;
char ch = getchar();
while(ch > '9'||ch < '0') {
if(ch == '-') {
f = -1;
}
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = x * 10 + (int)(ch - 48);
ch = getchar();
}
x = x * f;
}
int ans = 0;
const int maxn = 30;
int n, k, x[maxn];
bool visited[maxn];
void dfs(int pos, int sum, int cnt) {
if(cnt == k) {
if(is_prime(sum)) {
ans++;
}
return;
}
for(int i = pos; i < n; i++) {
if(!visited[i]) {
visited[i] = true;
dfs(i, sum + x[i], cnt + 1);
visited[i] = false;
}
}
}
int main() {
read(n);
read(k);
for(int i = 0; i < n; i++) {
read(x[i]);
}
dfs(0, 0, 0);
cout << ans << endl;
return 0;
}
欢迎加入“不会算法一群菜鸟”,群号是⑥⑥①⑨②2025,这是我设置的一道很低的门槛用来阻止广告的。入群的验证暗号是:我爱编译原理