C語(yǔ)言趣味編程之平分七筐魚(yú)
題目描述
甲、乙、丙三位漁夫出海打魚(yú),他們隨船帶了21只籮筐。當(dāng)晚返航時(shí),他們發(fā)現(xiàn)有7筐裝滿(mǎn)了魚(yú),還有7筐裝了半筐魚(yú),另外7筐則是空的,由于他們沒(méi)有秤,只好通過(guò)目測(cè)認(rèn)為7個(gè)滿(mǎn)筐魚(yú)的重量是相等的,7個(gè)半筐魚(yú)的重量是相等的。在不將魚(yú)倒出來(lái)的前提下,怎樣將魚(yú)平分為3份?
分析
這題還有兩個(gè)隱形要求:三個(gè)人分得的籮筐數(shù)量相同(7只);列出所有的平分方法。
我的思路(參照網(wǎng)上他人方法)
首先,所有的魚(yú)所占的籮筐數(shù)為7+7*0.5=10.5只(7只滿(mǎn)筐和7只半筐),將它們平分成3份,那么每個(gè)人就能分到3.5只裝滿(mǎn)魚(yú)的籮筐(例如3只滿(mǎn)筐和1只半筐或者1只滿(mǎn)筐5只半筐等等)。
我們可以先遍歷出甲分到的裝滿(mǎn)魚(yú)的籮筐數(shù),然后再遍歷出乙分到的裝滿(mǎn)魚(yú)的籮筐數(shù),丙的滿(mǎn)筐魚(yú)籮筐數(shù)則為7-甲乙的滿(mǎn)筐魚(yú)的籮筐數(shù)之和。由于最后每個(gè)人都能分到3.5筐魚(yú),所以他們最多可分配3只裝滿(mǎn)魚(yú)的籮筐。
確定完他們的滿(mǎn)筐魚(yú)籮筐數(shù)之后,接著遍歷甲乙分到的半筐魚(yú)籮筐數(shù),丙分到的半筐魚(yú)籮筐數(shù)則等于7-甲乙的半筐魚(yú)的籮筐數(shù)之和。由于目前他們分到的滿(mǎn)筐魚(yú)的籮筐數(shù)為整數(shù),而最終他們都必須分得3.5筐魚(yú),所以每個(gè)人至少要分到一只裝有半筐魚(yú)的籮筐,且一定是奇數(shù)只。
在分配完半筐魚(yú)的籮筐后,如果每個(gè)人所分到的魚(yú)的籮筐數(shù)為3.5(其實(shí)判斷甲乙即可),那么說(shuō)明該分配方式符合條件。
最后,每個(gè)人空筐的籮筐數(shù)=7-該人的滿(mǎn)筐魚(yú)籮筐數(shù)-該人的半筐魚(yú)籮筐數(shù)。
我的代碼還有一些可優(yōu)化的地方(可以刪去一些無(wú)效的循環(huán)次數(shù)),在網(wǎng)上參考部分有一個(gè)很不錯(cuò)的例子(我的思路和代碼就參考了該例子)。
代碼實(shí)現(xiàn)
#include <stdio.h> int main() { //甲乙丙分得的不同類(lèi)型籮筐數(shù)量 int fish_nums[3][3] = {0}; int i = 0, j = 0, k = 0, m = 0, n = 0; //甲分滿(mǎn)籮筐,最大3筐 for(i = 0; i <= 3; i++) { fish_nums[0][0] = i; //甲分得滿(mǎn)籮筐數(shù) //乙分滿(mǎn)籮筐,最大三筐 for(j = 0; j <= 3; j++) { fish_nums[1][0] = j; //乙分得滿(mǎn)籮筐數(shù) fish_nums[2][0] = 7 - i - j; //丙分得滿(mǎn)籮筐數(shù) if(fish_nums[2][0] > 3) continue; //超過(guò)3.5框 //甲分奇數(shù)個(gè)半籮筐,最少1個(gè),最多5個(gè)(其他人也要分) for(k = 1; k <= 5; k+=2) { if(fish_nums[0][0] + 0.5 * k == 3.5) break; } fish_nums[0][1] = k; //甲分得半籮筐數(shù) //乙分奇數(shù)個(gè)半籮筐,最少1個(gè),最多5個(gè)(其他人也要分) for(m = 1; m <= 5; m+=2) //乙分奇數(shù)個(gè)半籮筐 { if(fish_nums[1][0] + 0.5 * m == 3.5) break; } fish_nums[1][1] = m; //乙分得半籮筐數(shù) fish_nums[2][1] = 7 - k - m; //丙分得半籮筐數(shù) //甲分得空籮筐數(shù) fish_nums[0][2] = 7 - fish_nums[0][0] - fish_nums[0][1]; //乙分得空籮筐數(shù) fish_nums[1][2] = 7 - fish_nums[1][0] - fish_nums[1][1]; //丙分得空籮筐數(shù) fish_nums[2][2] = 7 - fish_nums[2][0] - fish_nums[2][1]; //打印匹配的結(jié)果 for(n = 0; n < 3; n++) { if(n == 0) printf("甲——"); else if(n == 1) printf("乙——"); else printf("丙——"); printf("滿(mǎn)筐:%d,半筐:%d,空筐:%d\n", fish_nums[n][0],\ fish_nums[n][1], fish_nums[n][2]); if(n == 2) printf("-------------------------------------\n"); } } } return 0; }
運(yùn)行結(jié)果
由于我考慮了針對(duì)甲乙丙三個(gè)不同的人的分法,所以最后結(jié)果有
6個(gè)
,如果不考慮三個(gè)人的身份,那么分法還需要除以3,即只有2種
(具體代碼可以參考下文的網(wǎng)上參考部分)
網(wǎng)上參考
原文鏈接:http://c.biancheng.net/cpp/html/3370.html
核心思路
- (1) 數(shù)組的每行或每列的元素之和都為7。
- (2) 對(duì)數(shù)組的行來(lái)說(shuō),滿(mǎn)筐數(shù)加半筐數(shù)=3.5。
- (3) 每個(gè)人所得的滿(mǎn)筐數(shù)不能超過(guò)3筐。
- (4) 每個(gè)人都必須至少有1個(gè)半筐,且半筐數(shù)一定為奇數(shù)。
#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++) /*試探第一個(gè)人滿(mǎn)筐a[0][0]的值,滿(mǎn)筐數(shù)不能>3*/ { a[0][0]=i; for(j=i; j<=7-i&&j<=3; j++) /*試探第二個(gè)人滿(mǎn)筐a[1][0]的值,滿(mǎn)筐數(shù)不能>3*/ { a[1][0]=j; if((a[2][0]=7-j-a[0][0])>3) continue; /*第三個(gè)人滿(mǎn)筐數(shù)不能>3*/ if(a[2][0]<a[1][0]) break; /*要求后一個(gè)人分的滿(mǎn)筐數(shù)大于等于前一個(gè)人,以排除重復(fù)情況*/ for(k=1; k<=5; k+=2) /*試探半筐a[0][1]的值,半筐數(shù)為奇數(shù)*/ { a[0][1]=k; for(m=1; m<7-k; m+=2) /*試探半筐a[1][1]的值,半筐數(shù)為奇數(shù)*/ { a[1][1]=m; a[2][1]=7-k-m; /*判斷每個(gè)人分到的魚(yú)是 3.5筐,flag為滿(mǎn)足題意的標(biāo)記變量*/ 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]; /*計(jì)算應(yīng)得到的空筐數(shù)量*/ else flag=0; /*不符合題意則置標(biāo)記為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; }
原文結(jié)果:
以上所述是小編給大家介紹的C語(yǔ)言趣味編程之平分七筐魚(yú),希望對(duì)大家有所幫助。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
C++超詳細(xì)講解RTTI和cast運(yùn)算符的使用
RTTI(Runtime Type Identification)是“運(yùn)行時(shí)類(lèi)型識(shí)別”的意思。C++引入這個(gè)機(jī)制是為了讓程序在運(yùn)行時(shí)能根據(jù)基類(lèi)的指針或引用來(lái)獲得該指針或引用所指的對(duì)象的實(shí)際類(lèi)型,cast強(qiáng)制轉(zhuǎn)換運(yùn)算符是一種特殊的運(yùn)算符,它把一種數(shù)據(jù)類(lèi)型轉(zhuǎn)換為另一種數(shù)據(jù)類(lèi)型2022-08-08C++中strstr函數(shù)的實(shí)現(xiàn)方法總結(jié)
這篇文章主要介紹了C++中strstr函數(shù)的實(shí)現(xiàn)方法總結(jié)的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10C語(yǔ)言解決百錢(qián)買(mǎi)百雞問(wèn)題
本文給大家分享的是一個(gè)經(jīng)典的算法(百元百雞)的C語(yǔ)言版的解決方法,使用的是比較偷懶的窮舉法,有需要的小伙伴可以參考下。2016-02-02C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單通訊錄系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單通訊錄系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07C語(yǔ)言中的數(shù)組和指針匯編代碼分析實(shí)例
這篇文章主要介紹了C語(yǔ)言中的數(shù)組和指針匯編代碼分析實(shí)例,本文用一則C語(yǔ)言例子來(lái)得到對(duì)應(yīng)的匯編代碼,并一一注解每句匯編代碼的含義,需要的朋友可以參考下2015-06-06C語(yǔ)言之實(shí)現(xiàn)單鏈表指定結(jié)點(diǎn)的插入方式
這篇文章主要介紹了C語(yǔ)言之實(shí)現(xiàn)單鏈表指定結(jié)點(diǎn)的插入方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07