10拆分成4個數 四個數中只要有一個數&>=5 就可以 求這樣的組合有多少種


我們分別設置4個數,按照題設既然是分,那麼每個數都不為0,最小為1,由此可知每個數最小為1最大為7,按照如下循環求組合

#include&
int main()
{
int A,B,C,D,n;//分為ABCD四個數,n僅為計算該程序最終循環次數,非必要
int a,b,c,d;
for(A=1;A&<=7;A++)//按照題設,每個數最小為1最大為7 for(B=1;B&<=7;B++) for(C=1;C&<=7;C++) for(D=1;D&<=7;D++) { a=(A&>=5);//當其中一個數大於等於5的情況
b=(B&>=5);
c=(C&>=5);
d=(D&>=5);
n++;//計數用
if((a+b+c+d==1)(A+B+C+D==10))//四個數當中有大於等於5的情況只出現一次且四個數相加等於10
printf("A=%d,B=%d,C=%d,D=%d,運行%d次
",A,B,C,D,n);
}
return 0;
}

如果考慮輸出相同的情況,比如類似有朋友提到1,1,1,7和7,1,1,1算相同的話,那麼可以將程序做如下修改:

#include&
int main()
{
int A,B,C,D,n;//分為ABCD四個數,n僅為計算該程序最終循環次數,非必要
int a,b,c,d;
for(A=5;A&<=7;A++)//按照題設,每個數最小為1最大為7,修改後要求A恆定大於等於5,故A初始賦值5 for(B=1;B&<=7;B++) for(C=1;C&<=7;C++) for(D=1;D&<=7;D++) { a=(A&>=5);//當其中一個數大於等於5的情況
b=(B&>=5);
c=(C&>=5);
d=(D&>=5);
n++;//計數用
if((a+b+c+d==1)(A+B+C+D==10)(B&>=C&>=D))//新增條件B&>=C&>=D,以過濾同樣排序的結果
printf("A=%d,B=%d,C=%d,D=%d,運行%d次
",A,B,C,D,n);
}
return 0;
}

在最早的代碼基礎上把結果排序再比較我沒有試,但我想也是可以實現的,但是代碼修改會比較多,也要比現在複雜,盡量最少修改符合不輸出同樣結果的話,修改部分一個是改變了A的初始值,以實現僅A為這個最大數的情況,然後是加入B&>=C&>=D這個條件,以過濾剩餘三個數相同的值不同的排序。

注意:B&>=C&>=D這個條件不能畫蛇添足為A&>=B&>=C&>=D。


int func()

{

return 4;

}


答主的那個答案我覺得想法非常好,但是最後的輸出不是直接的答案,這個比較尷尬~

稍微修改一下

#include&
int main()
{
int A,B,C,D,n;//分為ABCD四個數,n僅為計算該程序最終循環次數,非必要
int a,b,c,d;
for(A=1;A&<=7;A++)//按照題設,每個數最小為1最大為7 for(B=1;B&<=7;B++) for(C=1;C&<=7;C++) for(D=1;D&<=7;D++) { a=(A&>=5);//當其中一個數大於等於5的情況
b=(B&>=5);
c=(C&>=5);
d=(D&>=5);
//n++;//計數用
if((a+b+c+d==1)(A+B+C+D==10))//四個數當中有大於等於5的情況只出現一次且四個數相加等於10
printf("A=%d,B=%d,C=%d,D=%d,滿足%d次
",A,B,C,D,++n);
}
getchar();
return 0;
}

代碼輸出

A=1,B=1,C=1,D=7,滿足1次
A=1,B=1,C=2,D=6,滿足2次
A=1,B=1,C=3,D=5,滿足3次
A=1,B=1,C=5,D=3,滿足4次
A=1,B=1,C=6,D=2,滿足5次
A=1,B=1,C=7,D=1,滿足6次
A=1,B=2,C=1,D=6,滿足7次
A=1,B=2,C=2,D=5,滿足8次
A=1,B=2,C=5,D=2,滿足9次
A=1,B=2,C=6,D=1,滿足10次
A=1,B=3,C=1,D=5,滿足11次
A=1,B=3,C=5,D=1,滿足12次
A=1,B=5,C=1,D=3,滿足13次
A=1,B=5,C=2,D=2,滿足14次
A=1,B=5,C=3,D=1,滿足15次
A=1,B=6,C=1,D=2,滿足16次
A=1,B=6,C=2,D=1,滿足17次
A=1,B=7,C=1,D=1,滿足18次
A=2,B=1,C=1,D=6,滿足19次
A=2,B=1,C=2,D=5,滿足20次
A=2,B=1,C=5,D=2,滿足21次
A=2,B=1,C=6,D=1,滿足22次
A=2,B=2,C=1,D=5,滿足23次
A=2,B=2,C=5,D=1,滿足24次
A=2,B=5,C=1,D=2,滿足25次
A=2,B=5,C=2,D=1,滿足26次
A=2,B=6,C=1,D=1,滿足27次
A=3,B=1,C=1,D=5,滿足28次
A=3,B=1,C=5,D=1,滿足29次
A=3,B=5,C=1,D=1,滿足30次
A=5,B=1,C=1,D=3,滿足31次
A=5,B=1,C=2,D=2,滿足32次
A=5,B=1,C=3,D=1,滿足33次
A=5,B=2,C=1,D=2,滿足34次
A=5,B=2,C=2,D=1,滿足35次
A=5,B=3,C=1,D=1,滿足36次
A=6,B=1,C=1,D=2,滿足37次
A=6,B=1,C=2,D=1,滿足38次
A=6,B=2,C=1,D=1,滿足39次
A=7,B=1,C=1,D=1,滿足40次


10拆分成4個數 四個數中只要有一個數&>=5 就可以 求這樣的組合有多少種

解決問題先看定義,問題清楚的才能解決

1+4+5和1+5+4算一個還是兩個,這之類的都需要嚴格進行定義


這題是一個普通生成函數模板題(

我還是重新描述一下題意:求有多少個四元祖 [公式] 滿足 [公式][公式]

那我們可以列出這四個數的生成函數:

對於a,b,c可以發現它們是一樣的,那麼 [公式]

對於d我們可以列出 [公式]

那麼答案就是 [公式][公式] 的係數直接做卷積就行啦/cy


重新想了一下並做了擴展,原答案在分割線下面。

探討:

  1. 0 是否可選? 我認為不可選,原因在原答里已經說了;
  2. 拆分的數裡面是否可重複選擇?比如各位的程序里有 [1,1,1,7] [1,1,7,1] [1,7,1,1] [7,1,1,1]的運行答案,我以為這些本質上是一種組合,只是同個組合的不同排列而已;如果輸出每一種合乎要求的組合,是不是更有意義一些?
  3. 按照概率論中排列組合的意思,該題等價於:輸出在區間 (0,10) 裡面選擇4個不同數的組合,並滿足4個數的和等於10且至少有一個&>=5;
  4. 所以拓展為,輸出在N個數裡面選擇M個數 (N&>M)的組合數,且列出滿足組合元素的和等於S且任意元素大於等於 Num.

思路:

  1. 從命令行輸入N、M,做一些合規性檢查;
  2. 構造可選數的集合,[1, N),見函數 BuildNums(int n);
  3. 遞歸法球N個數裡面選M個數的組合,見函數 Combo();
  4. 在第3步求出的組合里,進一步篩選符合要求的記錄,見函數 otherConditions。

常式:
/*
ComboTest.java - Test to output the combinations of C(N,M), with other conditions.
Copyright: freeants, All rights reserved.
*/
import java.util.Arrays;
import java.util.Vector;

public class CombTest {
static int cnt = 0; // counter of satisfactory combinations
static int S = 10, Num = 5; // one of the conditon that sum needs to equal to 10
static int N, M; // for C(N, M)
static Vector& v;// holds each number in [1, N)

/*
* Test if its an integer input
*/
static boolean isInteger(final String s) {
boolean isValidInteger = false;
try {
Integer.parseInt(s);
// s is valid integer
isValidInteger = true;
} catch (final NumberFormatException ex) {
// s is not valid integer
}
return isValidInteger;
}

/*
* Build vector v, holds each number in [1, N)
*/
static void BuildNums(int n) {
v = new Vector&();
for (int i = 0; i &< N; i++) v.add(i); System.out.println("Number choices: " + v); } static void otherConditions(int[] solution, int s) { int sum = 0; boolean c = false; for (int i = 0; i &< solution.length; i++) { sum += solution[i]; if (solution[i] &>= Num) {
c = true;
}
}
if ((sum == S) c) {
System.out.println(++cnt + ":" + Arrays.toString(solution));
}

}

/*
* Calculate the Combinations of C[N,M]
* @param v: holds all number choices
* @param solutions: M
* @param start: starting index
* @param pos: current position index
*/
static int Combo(Vector& v, int[] solution, int start, int pos) {
if ((pos == solution.length)) {
// print combinations when other conditions meet
otherConditions(solution, S);
return 1;
}
int count = 0;
for (int i = start; i &< v.size(); i++) { solution[pos++] = v.get(i); count += Combo(v, solution, i + 1, pos); pos--; } return count; } public static void main(String[] args) { // Ask for input N, M at start if (args.length != 2) { System.out.println("Usage: ComboTest N M // N &> M and both integers");
return;
}
// Input validations
if (isInteger(args[0]) isInteger(args[1])) {
N = Integer.valueOf(args[0]);
M = Integer.valueOf(args[1]);
} else {
System.out.println("Note: M &> N and need to be integers.");
return;
}

int[] Solution = new int[M];

try {
// Build Vector v and fillin with [0-N)
BuildNums(N);
// Calculate Combo of C(N,M) with other conditions
System.out.println(
Combo(v, Solution, 0, 0) + " solutions in total and " + cnt + " combos meet requirements.");
} catch (Exception e) {
// Handle exception
System.out.println("
Error:" + e.getLocalizedMessage());
}
}
}

輸出:

% java CombTest.java 10 4
Number choices: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1:[0, 1, 2, 7]
2:[0, 1, 3, 6]
3:[0, 1, 4, 5]
4:[0, 2, 3, 5]
210 solutions in total and 4 combos meet requirements.
% java CombTest.java 10 4
Number choices: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
210 solutions in total and 0 combos meet requirements.
% java CombTest.java 10 3
Number choices: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
1:[1, 2, 7]
2:[1, 3, 6]
3:[1, 4, 5]
4:[2, 3, 5]
120 solutions in total and 4 combos meet requirements.

可以看到,對於原題,如果選擇包括0,那麼有4種組合情況滿足要求(不是排列,組合數沒有重複)。如果選擇不能有0,那麼10選4無解,但10選3有解。

參考:

如何通俗的解釋排列公式和組合公式的含義??

www.zhihu.com圖標

(以下為原答案)


疑問:

是否等價於在 [1, 9] 之間任意選擇4個數的組合 C(10, 4),其中要滿足4個數的和是10且有一個數&>=5啊?0 是否可選?(如果選了其實等價於拆分成3個數)

如果等價的話,有一個是5或更大,其餘三個數必定小於5,同時還滿足三個數的和小於等於5,最接近的是[1, 2, 3, 5],所以滿足要求的組合是0種。如果可以包括0,有4種。

思路:

  1. 求C(10,4)注意是組合C而不是排列 P,存儲每一種組合到堆棧中;
  2. 找出堆棧里符合和為10且某數&>=5的輸出。

部分輸出:

% java ComboOfN.java 10 4
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1:[0, 1, 2, 7]
2:[0, 1, 3, 6]
3:[0, 1, 4, 5]
4:[0, 2, 3, 5]
210 solutions in total and 4 combos meet requirements.
%

可以看到只有4個組合滿足要求,這是可選0的情況。不包括零的話此題無解。


#include&

int main()

{

int A,B,C,D,n;//分為ABCD四個數,n僅為計算該程序最終循環次數,非必要

int a,b,c,d;

for(A=1;A&<=7;A++)//按照題設,每個數最小為1最大為7

for(B=A;B&<=7;B++)

for(C=B;C&<=7;C++)

for(D=D;D&<=7;D++)

{

a=(A&>=5);//當其中一個數大於等於5的情況

b=(B&>=5);

c=(C&>=5);

d=(D&>=5);

//n++;//計數用

if((a+b+c+d==1)(A+B+C+D==10))//四個數當中有大於等於5的情況只出現一次且四個數相加等於10

printf("A=%d,B=%d,C=%d,D=%d,滿足%d次
",A,B,C,D,++n);

}

getchar();

return 0;

}

在前人的基礎上修一下,把多餘的排列去掉


for循環i,5到7

for循環j,1到8-i

for循環k,1到9-i-j

計數++

湊合著看,意會一下


推薦閱讀:
相关文章