洛谷p1036 選數解析

題目描述

已知 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<n1n20,k<n)io

x_1,x_2,…,x_n (1 \le x_i \le 5000000)x1,x2,,xn(1xi5000000)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];        }    } } 而遞歸函數則適用任何從多少個整數中挑選多少個數進行相加;

相關文章
相關標籤/搜索