求问大佬这是什么情况(附源码)
  • 板块学术版
  • 楼主chtholly3
  • 当前回复8
  • 已保存回复8
  • 发布时间2023/1/12 13:42
  • 上次更新2023/10/24 04:36:12
查看原帖
求问大佬这是什么情况(附源码)
884496
chtholly3楼主2023/1/12 13:42

#include<bits/stdc++.h>
using namespace std;
const int N=1e8;
vector<int>prime;//数组内容用来存质数
bool isprime[N]={1,1};//下标用来判断是否为质数,其中0和1先定下
long long cnt = 0;//cnt用来给prime提供下标
int a[21];
int Euler(long long n) {
	cnt = 0;
	for (long long i = 2; i < n+1; i++) {
		isprime[i] = 0;
	}
	for (long long i = 2; i < n+1; i++)//注意初始化,以第一个质数2为起点
	{
		if (isprime[i] == 0) {
			prime.push_back(i);
			cnt++;
		}
		for (long long j = 0; j < cnt ; j++)//j从1开始,结尾也要后移一位
		{
			if (i * prime[j] >n )break;
			isprime[prime[j] * i] = 1;//所有的质数乘i是合数
			if (i % prime[j] == 0)break;//防止多筛的关键
		}
	}
	if (!isprime[n])return 1;
	return 0;
}
int n,k;
long long ans;
void dfs(int m, long long sum, int startx) {//m用来判断是否已达到k,sum用来求和(传入0来实现初始化),startx是每次开始的位置
	if (m == k) {
		if (Euler(sum))
			ans++;
		return;
	}
	for (int i = startx; i < n; i++)
		dfs(m + 1, sum + a[i], i + 1);//将startx向后一位
		/*这部分实现的是从m元中挑选k元,如果没有求和要求,可以去掉参数sum*/
		/*而实现的原理是(下标)不降原则,也即下标不会走回头路,如1 5 4这种情况*/
	return;
}
int main(){
	scanf("%d%d", &n, &k);
	for (int i = 0; i < n; i++) {
		scanf("%d", &a[i]);
	}
	dfs(0, 0, 0);//一个用来对m个数据中k元组进行求和或求积的dfs
	printf("%lld", ans);
	return 0;
}
2023/1/12 13:42
加载中...