洛谷題解 P1036 選數

2021-10-24 08:59:23 字數 1512 閱讀 6203

洛谷,

已知 n 個整數 x1​,x2​,…,xn​,以及1個整數k(k3+7+12=22

3+7+19=29

7+12+19=38

3+12+19=34

現在,要求你計算出和為素數共有多少種。

例如上例,只有一種的和為素數:3+7+19=29。

鍵盤輸入,格式為:

n,k (1≤n≤20,kx1​,x2​,…,xn​ (1 ≤ xi​ ≤ 5000000)

螢幕輸出,格式為: 1個整數(滿足條件的種數)。

4 3

3 7 12 19

1
按照洛谷提單的分類,將本題分類為暴力列舉。本人比較菜,一下沒有想出暴力列舉的想法,難道最高用 if 判斷寫出 20 個 for 迴圈進行列舉?但是本題一看就是乙個搜尋題。

根據樣例輸入,我們知道 n=4,k=3,對應的 4 個資料為 3 7 12 19。這樣,我們可以列出組合有如下幾個:

3+7+12

3+7+19

7+12+19

根據題目,我們知道任何乙個 x 最大值為 5,000,000,也即是 5e6。k 的最大值為 19,那麼這 k 個資料的總和為 5e6*19<5e6*2e1=10e7=1e8,所以用 int 表示足夠。

為了記錄整個搜尋過程,我們可以考慮設計如下幾個變數進行跟蹤。

第乙個變數:表示當前搜尋到哪個資料,也就是陣列的下標,用 idx 表示。

第二個變數:表示當前搜尋的資料總和,用 sum 表示。

第三個變數:表示當前搜尋包含幾個資料,用 step 表示。

idx=0。表示我們從陣列下標為 0 的資料開始。

sum=0。表示當前的資料總和為零。

step=0。表示還沒有開始搜尋。

根據題目,我們知道任何一次搜尋退出的條件應該有乙個:

1、搜尋的總數達到了 k 次。也就是 step>=k。

很簡單,可以使用乙個 vis 陣列表示當前的資料是否可見。

但是這樣的方案會導致有多個重複資料給搜尋到,我們需要使用到排列數中的不降原則,來消滅重複。

使用「不降原則」消滅重複。我們可以觀察手工寫出的組合數,來體會這個「不降原則」。

#include using namespace std;

bool isprime(int x)

for (int i=2; i*i<=x; i++)

}return true;

}int n, k;

const int maxn=2e1+4;

int sj[maxn];

bool vis[maxn];//

int ans=0;

/*第乙個引數:索引

第二個引數:當前總和

第三個引數:搜尋到第幾個數

*/void dfs(int idx, int sum, int step)

dfs(0, 0, 0);

cout

}

洛谷P1036選數題解 zhengjun

題目描述 已知 n nn 個整數 x1,x2,x nx 1,x 2,x n x1 x2 xn 以及1 11 個整數 k kk k k n 從 n nn 個整數中任選 k kk 個整數相加,可分別得到一系列的和。例如當 n 4 k 3 n 4,k 3 n 4,k 3,4 44 個整數分別為 3,7 1...

洛谷P1036 選數

已知 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。...

洛谷 P1036選數

已知 n 個整數 x1,x2,xn以及1個整數k k3 7 12 22 3 7 19 29 7 12 19 38 3 12 19 34 現在,要求你計算出和為素數共有多少種。例如上例,只有一種的和為素數 3 7 19 29。輸入格式 鍵盤輸入,格式為 n,k 1 n 20,kx1,x2,xn 1 x...