題目描述
甲、乙、丙三位漁夫出海打魚,他們隨船帶了21只籮筐。當晚返航時,他們發現有7筐裝滿了魚,還有7筐裝了半筐魚,另外7筐則是空的,由于他們沒有秤,只好通過目測認為7個滿筐魚的重量是相等的,7個半筐魚的重量是相等的。在不將魚倒出來的前提下,怎樣將魚平分為3份?
分析
這題還有兩個隱形要求:三個人分得的籮筐數量相同(7只);列出所有的平分方法。
我的思路(參照網上他人方法)
首先,所有的魚所占的籮筐數為7+7*0.5=10.5只(7只滿筐和7只半筐),將它們平分成3份,那么每個人就能分到3.5只裝滿魚的籮筐(例如3只滿筐和1只半筐或者1只滿筐5只半筐等等)。
我們可以先遍歷出甲分到的裝滿魚的籮筐數,然后再遍歷出乙分到的裝滿魚的籮筐數,丙的滿筐魚籮筐數則為7-甲乙的滿筐魚的籮筐數之和。由于最后每個人都能分到3.5筐魚,所以他們最多可分配3只裝滿魚的籮筐。
確定完他們的滿筐魚籮筐數之后,接著遍歷甲乙分到的半筐魚籮筐數,丙分到的半筐魚籮筐數則等于7-甲乙的半筐魚的籮筐數之和。由于目前他們分到的滿筐魚的籮筐數為整數,而最終他們都必須分得3.5筐魚,所以每個人至少要分到一只裝有半筐魚的籮筐,且一定是奇數只。
在分配完半筐魚的籮筐后,如果每個人所分到的魚的籮筐數為3.5(其實判斷甲乙即可),那么說明該分配方式符合條件。
最后,每個人空筐的籮筐數=7-該人的滿筐魚籮筐數-該人的半筐魚籮筐數。
我的代碼還有一些可優化的地方(可以刪去一些無效的循環次數),在網上參考部分有一個很不錯的例子(我的思路和代碼就參考了該例子)。
代碼實現
#include <stdio.h> int main() { //甲乙丙分得的不同類型籮筐數量 int fish_nums[3][3] = {0}; int i = 0, j = 0, k = 0, m = 0, n = 0; //甲分滿籮筐,最大3筐 for(i = 0; i <= 3; i++) { fish_nums[0][0] = i; //甲分得滿籮筐數 //乙分滿籮筐,最大三筐 for(j = 0; j <= 3; j++) { fish_nums[1][0] = j; //乙分得滿籮筐數 fish_nums[2][0] = 7 - i - j; //丙分得滿籮筐數 if(fish_nums[2][0] > 3) continue; //超過3.5框 //甲分奇數個半籮筐,最少1個,最多5個(其他人也要分) for(k = 1; k <= 5; k+=2) { if(fish_nums[0][0] + 0.5 * k == 3.5) break; } fish_nums[0][1] = k; //甲分得半籮筐數 //乙分奇數個半籮筐,最少1個,最多5個(其他人也要分) for(m = 1; m <= 5; m+=2) //乙分奇數個半籮筐 { if(fish_nums[1][0] + 0.5 * m == 3.5) break; } fish_nums[1][1] = m; //乙分得半籮筐數 fish_nums[2][1] = 7 - k - m; //丙分得半籮筐數 //甲分得空籮筐數 fish_nums[0][2] = 7 - fish_nums[0][0] - fish_nums[0][1]; //乙分得空籮筐數 fish_nums[1][2] = 7 - fish_nums[1][0] - fish_nums[1][1]; //丙分得空籮筐數 fish_nums[2][2] = 7 - fish_nums[2][0] - fish_nums[2][1]; //打印匹配的結果 for(n = 0; n < 3; n++) { if(n == 0) printf("甲——"); else if(n == 1) printf("乙——"); else printf("丙——"); printf("滿筐:%d,半筐:%d,空筐:%d\n", fish_nums[n][0],\ fish_nums[n][1], fish_nums[n][2]); if(n == 2) printf("-------------------------------------\n"); } } } return 0; }
運行結果
由于我考慮了針對甲乙丙三個不同的人的分法,所以最后結果有6個,如果不考慮三個人的身份,那么分法還需要除以3,即只有2種(具體代碼可以參考下文的網上參考部分)
網上參考
核心思路
- (1) 數組的每行或每列的元素之和都為7。
- (2) 對數組的行來說,滿筐數加半筐數=3.5。
- (3) 每個人所得的滿筐數不能超過3筐。
- (4) 每個人都必須至少有1個半筐,且半筐數一定為奇數。
#include<stdio.h> int a[3][3], count; int main() { int i, j, k, m, n, flag; printf("It exists possible distribtion plans:\n"); for(i=0; i<=3; i++) /*試探第一個人滿筐a[0][0]的值,滿筐數不能>3*/ { a[0][0]=i; for(j=i; j<=7-i&&j<=3; j++) /*試探第二個人滿筐a[1][0]的值,滿筐數不能>3*/ { a[1][0]=j; if((a[2][0]=7-j-a[0][0])>3) continue; /*第三個人滿筐數不能>3*/ if(a[2][0]<a[1][0]) break; /*要求后一個人分的滿筐數大于等于前一個人,以排除重復情況*/ for(k=1; k<=5; k+=2) /*試探半筐a[0][1]的值,半筐數為奇數*/ { a[0][1]=k; for(m=1; m<7-k; m+=2) /*試探半筐a[1][1]的值,半筐數為奇數*/ { a[1][1]=m; a[2][1]=7-k-m; /*判斷每個人分到的魚是 3.5筐,flag為滿足題意的標記變量*/ for(flag=1,n=0; flag&&n<3; n++) if(a[n][0]+a[n][1]<7&&a[n][0]*2+a[n][1] == 7) a[n][2]=7-a[n][0]-a[n][1]; /*計算應得到的空筐數量*/ else flag=0; /*不符合題意則置標記為0*/ if(flag) { ++count; printf("No.%d Full basket Semi-basket Empty\n", count); for(n=0; n<3; n++) printf(" fisher %c: %d %d %d\n",'A'+n, a[n][0], a[n][1], a[n][2]); } } } } } return 0; }
原文結果:
以上所述是小編給大家介紹的C語言趣味編程之平分七筐魚,希望對大家有所幫助。在此也非常感謝大家對服務器之家網站的支持!
原文鏈接:https://blog.csdn.net/weixin_43772810/article/details/121432613