3. [2002年NOIP普及组] 选数
摘要:
从n个数里选k个作和,是素数的有多少个
分析:
这其实是要我们找全排列的无顺序子集、
子集:easy,位数改变为k即可
无顺序:
1.线性函数单调性(虽然看起来很高级但是不是最优的)
排序后数据顺次入栈,保证进入答案桶的每一个值都要大于前一个
2.改变for循环临界条件
排序(保证不会重复) 每次出栈后都从此元素的下一个元素入栈(初始条件)
从此元素开始计算个数(终止条件)
代码1:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 //如何实现无序全排列? 7 //进行排序,保证单调性即可 8 int n, k; 9 int a[100]; 10 struct dingyi{ 11 int num; 12 int data; 13 }ans[100]; 14 bool vis[100]; 15 int cnt; 16 int endd; 17 void per(int step); 18 bool prime(int x); 19 int main() 20 { 21 cin>>n>>k; 22 for(int i=1;i<=n;i++) 23 cin>>a[i]; 24 sort(a+1,a+n+1); 25 26 per(1);//对应好!!! 27 28 cout<<cnt; 29 return 0; 30 } 31 int t=1; 32 void per(int step) 33 { 34 if(step==k+1) 35 { 36 endd=0;//赋初值 37 for(int i=1;i<=k;i++) 38 endd+=ans[i].data;//检查++-- 39 if(prime(endd)==1) 40 cnt++; 41 else return ; 42 } 43 for(int i=1;i<=n;i++)//循环a[1-n]//在i上动手脚? 44 { 45 if(vis[i]==0&&a[i]>=ans[step-1].data&&i>ans[step-1].num)//第i个数没有被用过q且保证单调递增 //关于等号 46 { 47 vis[i]=1; 48 ans[step].data=a[i]; 49 ans[step].num=i; 50 51 per(step+1); 52 53 vis[i]=0; 54 } 55 } 56 } 57 bool prime(int x) 58 { 59 for(int i=2;i<=sqrt(x);i++) 60 { 61 if(x%i==0) return 0; 62 } 63 return 1; 64 }
代码2见元首大人,没时间写了()