[2002年NOIP普及组] 选数
首先确定第一个数,从第一个开始选,只能选到第n-k+1个,因为如果我们把第一个数选到第n-k+2个,在往后选怎么也不可能选到k个数
确定第一个数之后,要确定第二个数,只需再选k-1个数,从选择的第一个数的下一个数开始选,可以选到第n-(k-1)+1即n-k+2个,同理仍不能选到第n-k+3个
要确定第b个数,就从选择的第b-1个数的下一个数开始选,选到第n-k+b个
直到确定了第k个数,此时就出现一个了答案。
#include<iostream> #include<cmath> void combine(int a,int b,int n,int k,int *ans_data,void (*ans_call)(int *ans_data,int n,int *ans),int *ans) { if(b==k) return ans_call(ans_data,k,ans); for(int i=a;i<n-k+b+1;i++) ans_data[b]=i, combine(i+1,b+1,n,k,ans_data,ans_call,ans); } bool prime(int x) { int qrx=std::sqrt(x); for(int i=2;i<=qrx;i++) { if(x%i==0) return false; } return true; } void answer(int *ans_data,int n,int *ans) { int sum=0; for(int i=0;i<n;i++) sum+=ans[ans_data[i]+1]; if(prime(sum)) ans[0]++; } int main() { int value[100]; int n,k; std::cin>>n>>k; for(int i=1;i<=n;i++) std::cin>>value[i]; value[0]=0; int ans[100]; combine(0,0,n,k,ans,answer,value); std::cout<<value[0]; }