0
点赞
收藏
分享

微信扫一扫

P1036 [NOIP2002 普及组] 选数 (DFS)

IT影子 2022-01-13 阅读 46

传送门:P1036 [NOIP2002 普及组] 选数

题目描述:

输入格式

输出格式

思路

不降原则

因为是求种类数 ,所以需要去重,有点麻烦,所以就按照从大到小的顺序全排列

所以,从大到小输出,避免重复

具体实现,看下列代码,dfs函数的参数y,就代表当前选择的数字在全部数字中的位置是第y个,
for循环也是从第y个开始,省去了循环的时间,而且也在避免重复
之后dfs递归y+1,自动选择比它大的数字进行排序

void dfs(int x, int s, int y) {
	if (x == k && primer(s)) {
		cnt++;
		return ;
	}
	
	if (x >= k) return; 
	for(int i = y; i < n; i++) {
		if (!book[i]) {
			dfs(x + 1, s + a[i], i + 1);

		}
	}
}

代码详情

#include<stdio.h>
#include<string.h>
#include<math.h>
//普通方法现在我有点写不出来,只能学dalao的不降原则 
int a[30], n, k, cnt;
//int book[30];不用标记了,直接按大小选数字

//函数,判断是否是素数
int prime(int t) {
	int p = sqrt(t);
	if(t == 1)return 0;
	for(int i = 2; i <= p; i++) {
		if (t % i == 0)return 0;
	}
	return 1;
}
//x 现在是第几个数
//s 现在x个数的和
//y 选的第x个数 在所有的数中排第几
void dfs(int x, int s, int y) {
	if (x == k && primer(s)) {
		cnt++;
		return ;
	}
	
	if (x >= k) return; 
	for(int i = y; i < n; i++) {
		if (!book[i]) {
//			book[i] = 1;
//			s += a[i];
//			if (x == k && primer(s)) cnt++;
			dfs(x + 1, s + a[i], i + 1);
//			s -= a[i];
//			book[i] = 0;
		}
	}
//	dfs(x+1, s);
}

int main() {
	scanf("%d%d", &n, &k);
	for (int i = 0; i < n; i++) {
		scanf("%d", &a[i]);
	}
	dfs(0, 0, 0);
	printf("%d", cnt);
}
举报

相关推荐

0 条评论