P1036 [NOIP 2002 普及组] 选数

P1036 [NOIP 2002 普及组] 选数

题解

  • 理解题意

对于数组 1 1 1 4 6 ,可以选出3个1 4 6,这三个组合虽然内容相同,选的却是不同位置的数,所以算作不同组合。

选数字的时候要注意,我们只能在已经选的数后面选,保证不重选,其实如果每次都是在所有数中选,答案只需要处理一下

for(int i = 2 ; i <= m ; i ++) cnt /= i;//除以m的阶乘

这样也能对,但是会有一个测试点超时,因为dfs函数中做了太多的重复选择。

起初我的dfs函数是void dfs(int u,int ans),正确的dfs函数应该再传一个参数st作为选择的起点

ac✅️代码

#include<iostream>
#include<cmath>
using namespace std;
int v[50];
int cnt; 
int n,m;
bool is_p(int x)
{
	int maxn = sqrt(x);
	if( x == 1) return false;
	for(int i = 2; i <= maxn ; i ++) 
	{
		if(x % i == 0) return false;	
	}
	return true;
}


void dfs(int u,int ans,int st)
{
	if( u == m + 1 )
	{
		if(is_p(ans)) cnt ++;
		return ;
	}
	
	if(n - st < m - u + 1) return ;
	
	for(int i = st ; i < n ; i++)
	{
		dfs(u + 1,ans + v[i],i + 1);
	}
}

int main()
{
//	int n,m;
	cin>>n>>m;
	for(int i = 0 ; i < n ; i++)	
	{
		cin>>v[i];
	}
	
	dfs(1,0,0);
	cout<<cnt<<endl;
	
	return 0;
	
}
posted @ 2026-05-18 16:49  shuiwangrenjia  阅读(5)  评论(0)    收藏  举报