洛谷,
已知 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...