C++搜索與回溯算法之選數

選數

題目描述

已知 n 個整數 x1,x2,…,xn,以及一個整數 k(k<n)。從 n 個整數中任選 k 個整數相加,可分別得到一系列的和。例如當 n=4,k=3,4 個整數分別爲 3,7,12,19 時,可得全部的組合與它們的和爲: 3+7+12=22 3+7+19=29 7+12+19=38 3+12+19=34。 現在,要求你計算出和爲素數共有多少種。 例如上例,只有一種的和爲素數:3+7+19=29。

輸入

n,k (1≤n≤20,k<n) x1,x2,...,xn(1≤<=xi≤<=5000000)

輸出

一個整數(滿足條件的種數)。

樣例輸入

4 3
3 7 12 19

樣例輸出

1

解題

  這道題相當於在n集合中k個數的全排列的基礎上加上了判定素數了,但是不能把同一種排列調換順序,並且不用輸出所有排列方案。根據這種想法,我們可以很快寫出代碼,就像這樣:

#include<cmath>
#include<iostream>
using namespace std;
int n,k,x[21],num[21],cnt;
bool check()
{
    int sum=0;
    for(int i=1;i<=k;i++)
	sum+=num[i];
    for(int i=2;i<=sqrt(sum);i++)
        if(sum%i==0)
            return 0;
    return 1;
}
void dfs(int a,int last)
{
    for(int i=last;i<=n;i++)
    {
        num[a]=x[i];
        if(a==k&&check()) cnt++;
        else dfs(a+1,i+1);
    }
}
int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++)
        cin>>x[i];
    dfs(1,1);
    cout<<cnt;
}

    但是,我們也可以省去num數組直接定義全局變量sum,在dfs的語句裏直接用sum加上x[i],這樣省了計算總量的時間,也省了一個數組的空間,一舉兩得,代碼如下:

#include<cmath>
#include<iostream>
using namespace std;
int n,k,x[21],sum,cnt;
bool check()
{
    for(int i=2;i<=sqrt(sum);i++)
        if(sum%i==0)
            return 0;
    return 1;
}
void dfs(int a,int last)
{
    for(int i=last;i<=n;i++)
    {
        sum+=x[i];
        if(a==k&&check()) cnt++;
        dfs(a+1,i+1);
        sum-=x[i];
    }
}
int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++)
        cin>>x[i];
    dfs(1,1);
    cout<<cnt;
}

怎麼樣,是不是簡單多了?(~ ̄▽ ̄)
發佈了89 篇原創文章 · 獲贊 120 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章