已知 nn 個整數 x_1,x_2,…,x_nx1,x2,…,xn,以及11個整數kk(k<nk<n)。從nn個整數中任選kk個整數相加,可分別獲得一系列的和。例如當n=4,k=3n=4,k=3,44個整數分別爲3,7,12,193,7,12,19時,可得所有的組合與它們的和爲:html
3+7+12=223+7+12=22ios
3+7+19=293+7+19=29函數
7+12+19=387+12+19=38spa
3+12+19=343+12+19=34。htm
如今,要求你計算出和爲素數共有多少種。blog
例如上例,只有一種的和爲素數:3+7+19=293+7+19=29。遞歸
鍵盤輸入,格式爲:ci
n,kn,k(1 \le n \le 20,k<n1≤n≤20,k<n)io
x_1,x_2,…,x_n (1 \le x_i \le 5000000)x1,x2,…,xn(1≤xi≤5000000)table
屏幕輸出,格式爲: 11個整數(知足條件的種數)。
輸入
4 3 3 7 12 19 |
輸出
1 |
答案代碼:
#include<iostream> #include<math.h> using namespace std; int a[20]; int n,k; bool isprime(int n){ //判斷是否爲素數 for(int i=2;i<=sqrt(double(n));i++){ //注意sqrt()裏面必須是double類型 if(n%i==0) return false; } return true; } int xs(int k,int sum,int start,int end){ //選數,進行全組合,繼而得出總數,進行判斷 //k爲要選擇的數字的個數 //sum爲所選數字的總和 //start爲選擇的第一個數(防止重複) //end爲所給數的總數 if(k==0) { //當所選擇的數的個數爲0,選完全部的數之和,對這個數進行isprime(sum),即判斷是否爲素數,若是是返回false;不然返回true; // cout<<sum<<endl; return isprime(sum); //調用isprime函數判斷是否爲素數 } int s=0; for(int i=start;i<end;i++){ s+=xs(k-1,sum+a[i],i+1,end); //xs函數進行迭代,結束條件爲k==0;並返回ture,或false,將若是是true,s+=1;不然s+=0; } return s; } int main(){ cin>>n>>k; for(int i=0;i<n;i++){ cin>>a[i]; } cout<<xs(k,0,0,n); return 0; }
結果:
上述迭代代碼具體過程:
結果推導: (1)調用: xs(3,0,0,n); for(int i=0;i<n;i++){ s+=xs(2,a[i],i+1,n); } (2)二次調用函數 xs(2,a[i],1,n); for(int i=i+1;i<n;i++){ s+=xs(1,a[i]+a[i+1];i+1+1,n); } (3)三次調用函數 xs(1,a[i]+a[i+1];i+1+1,n); for(int i=i+1+1;i<n;i++){ s+=xs(0,a[i]+a[i+1]+a[i+1+1];i+1+1+1,n); } (4)四次調用函數 xs(0,a[i]+a[i+1]+a[i+1+1];i+1+1+1,n); if(k==0) return isprime(sum);由以上可知:調用了四次函數,第四次結束條件,從四個值中挑出三個相加與下式至關: for(int i=0;i<4;i++){ for(int j=i+1;j<4;j++){ for(int k=j+1;k<4;k++){ sum=a[i]+a[j]+a[k]; } } } 而遞歸函數則適用任何從多少個整數中挑選多少個數進行相加;