問題描述
設有n座山,計算機與人作爲比賽的雙方,輪流搬山。規定每次搬山數不能超過k座,誰搬最後一座誰輸。
遊戲開始時,計算機請人輸入山的總數n和每次允許搬山的最大數k,然後請人開始,等人輸入了需要搬走的山的數目後,計算機馬上打印出它搬多少座山,並提示尚餘多少座山。
雙方輪流搬山直到最後一座山搬完爲止。計算機會顯示誰是贏家,並問人是否要繼續比賽。如果人不想玩了,計算機便會統計出共玩了幾局,雙方勝負如何。
問題分析
程序中先輸入山的座數,要求每次搬山的最大數,從而找出最佳的搬山座數以獲得遊戲的勝利。
程序在若干次遊戲結束後還記錄了電腦跟人的勝負次數。程序中應用了條件語句、循環語句和邏輯判斷語句來實現功能。
在有n座山的情況下,計算機爲了將最後一座山留給人,而且又要控制每次搬山的數目不超過最大數k,應搬山的數目要滿足關係:(n-1)%(k+1)。
算法設計
計算機參加遊戲時應遵循下列原則:
(1) 當剩餘山的數目-1≤可移動的最大數k時,計算機要移(剩餘山數目-1)座,以便將最後一座山留給人。
(2) 對於任意正整數x,y,一定有:0≤x%(y+1)≤y
在有n座山的情況下,計算機爲了將最後一座山留給人,而且又要控制每次搬山的數目不超過最大數k,則它應搬山的數目要滿足下列關係:(n-1)%(k+1)
如果算出結果爲0,即整除無餘數,則規定只搬一座山,以防止冒進後發生問題。
呈上代碼:
#include
int main()
{
int n, k, x, y, cc, pc, g;
printf("搬山遊戲");
printf("遊戲開始");
pc=cc=0;
g=1;
for( ; ; )
{
printf("No.%2d game ", g++);
printf("-------------");
printf("那裏有多少座山?");
scanf("%d", &n); /*讀入山的總數*/
if(!n)
break;
printf("每次允許多少座山?");
do
{
scanf("%d", &k); /*讀入允許的搬山數*/
if(k>n || k<1) /*判斷搬山數*/
printf("再說一遍!");
}
while(k>n || k<1);
do
{
printf("你希望多少山搬走?");
scanf("%d",&x);
if(x<1 || x>k || x>n) /*判斷搬山數是否符合要求*/
{
printf("不符合要求,請再次輸入!");
continue;
}
n-=x;
printf("現在還剩下%d座山.", n);
if(!n)
{
printf("……………我贏了,你輸了。……………");
cc++;
}
else
{
y=(n-1)%(k+1); /*求出最佳搬山數*/
if(!y)
y=1;
n-=y;
printf("電腦一走了 %d 座山.", y);
if(n)
printf(" 現在還剩下%d座山.", n);
else
{
printf("……………我輸了,你贏了。………………");
pc++;
}
}
}
while(n);
}
/*打印結果*/
printf("總共進行了遊戲%d.", cc+pc);
printf("你的得分是勝利%d,輸了%d.", pc, cc);
printf("我的得分是勝利%d,輸了%d.", cc, pc);
return 0;
}
結果如下:
搬山遊戲
遊戲開始
No. 1 game
-------------
那裏有多少座山?10
每次允許多少座山?3
你希望多少山搬走?1
現在還剩下9座山.
電腦一走了 1 座山.
現在還剩下8座山.
你希望多少山搬走?3
現在還剩下5座山.
電腦一走了 1 座山.
現在還剩下4座山.
你希望多少山搬走?2
現在還剩下2座山.
電腦一走了 1 座山.
現在還剩下1座山.
你希望多少山搬走?1
現在還剩下0座山.
……………我贏了,你輸了。……………
如圖:
對於熱愛編程的人來說,有一羣一起學習一起解答的小夥伴很重要!
小編有一個C/C++編程學習交流俱樂部,【點擊進入】!
還有編程學習文件(源碼,零基礎教程,項目實戰教學視頻),歡迎初學者和正在進階中的小夥伴們!