問題 G: 汽水瓶 時間限制: 1 Sec 內存限制: 128 MB 提交: 93 解決: 45 201501010119 提交狀態討論版 題目描述 有這樣一道智力題:「某商店規定:三個空汽水瓶能夠換一瓶汽水。小張手上有十個空汽水瓶,她最多能夠換多少瓶汽水喝?」答案是5瓶,方法以下:先用9個空瓶子換3瓶汽水,喝掉3瓶滿的,喝完之後4個空瓶子,用3個再換一瓶,喝掉這瓶滿的,這時候剩2個空瓶子。而後你讓老闆先借給你一瓶汽水,喝掉這瓶滿的,喝完之後用3個空瓶子換一瓶滿的還給老闆。若是小張手上有n個空汽水瓶,最多能夠換多少瓶汽水喝? 輸入 輸入文件最多包含10組測試數據,每一個數據佔一行,僅包含一個正整數n(1<=n<=100),表示小張手上的空汽水瓶數。n=0表示輸入結束,你的程序不該當處理這一行。 輸出 對於每組測試數據,輸出一行,表示最多能夠喝的汽水瓶數。若是一瓶也喝不到,輸出0。 樣例輸入 Copy 3 10 81 0 樣例輸出 Copy 1 5 40
看樣例:輸入10,9個瓶子換三瓶能夠喝的汽水=》n=10/3=3; 現有的空瓶子=喝掉的三瓶(變爲空瓶子)+剩下的一個空瓶=》10/3+10%3=4;四個空瓶子取三個還能夠換飲料,發現回到了最初的步驟:擁有的空瓶子數量/3;
直到擁有的空瓶子剩下兩個,向老闆接借一個(+1),除以3就兌換完汽水啦~
其實吧,想要更簡單的代碼就直接觀察樣例,發現答案就是輸入的n除以2(固然是計算機裏的整除)
#include <bits/stdc++.h> using namespace std; int main() { int n; //空瓶子的數量 while(scanf("%d",&n)&&n) { int a; //喝的汽水數量 a=0; //注意歸零 while(n>1) //空瓶子大於等於2能夠換汽水 { a=a+n/3; //喝的汽水+空瓶子換的汽水 n=n%3+n/3; //上次換汽水剩下的瓶子+空瓶子換的汽水(喝完了就變成空瓶子了) if(n==2) //特殊狀況,每次循環判斷一次 n++; } cout<<a<<endl; } return 0; }
問題 H: 蜂房 時間限制: 1 Sec 內存限制: 128 MB 提交: 1 解決: 1 201501010119 提交狀態討論版 題目描述 有一隻通過訓練的蜜蜂只能爬向右側相鄰的蜂房,不能反向爬行。請編程計算蜜蜂從蜂房a爬到蜂房b的可能路線數。 其中,蜂房的結構以下所示。 (咳咳,圖不見了) 輸入 多組數據輸入,每組數據包含兩個正整數a, b,且 a<b。 輸出 蜜蜂從蜂房a爬到蜂房b的可能路線數。 樣例輸入 Copy 1 2 3 4 樣例輸出 Copy 1 1
1、a->b的路徑能夠化歸於1->(b-a)的路徑狀況c++
由於不能反向爬行,且只能爬右側相鄰蜂房,因此決定了能夠化歸的特殊性(老師上課也講過了)編程
2、遞歸的思想函數
假設1->5,反過來看:到達5有兩個選擇,從3到達,或者從4到達,因此這個數量是由前面兩種狀況決定的;那麼到達3也有兩種狀況,要麼從1要麼從2;到達4同理;測試
因此咱們獲得一個規律,要到達的目的地數量由前兩種方法決定;spa
因此這也是遞歸的核心;code
而遞歸的終止條件是:1->1;1->2;1->3;blog
#include <bits/stdc++.h> using namespace std; int f(int n) { if(n<4) //基本條件 return n; else { return f(n-1)+f(n-2); //遞歸表達式 } } int main() { int a,b; while(scanf("%d%d",&a,&b)!=EOF) { int n; n=b-a; cout<<f(n)<<endl; } return 0; }
問題 K: 骨牌覆蓋 時間限制: 1 Sec 內存限制: 128 MB 提交: 0 解決: 0 201501010119 提交狀態討論版 題目描述 用大小爲1×2的骨牌鋪滿一個大小爲2×n的長方形方格,編寫一個程序,輸入n,輸出鋪放方案總數。例如,輸入n=3,即大小爲2×3的方格,輸出3。3種骨牌鋪放方案以下圖所示: 輸入 多組測試用例,每一組是一個正整數。 輸出 每組輸出佔一行。 只須要輸出鋪放方案總數,不須要輸出具體的鋪放方案。 樣例輸入 Copy 3 樣例輸出 Copy 3
這個題和上一題代碼其實差很少,主要也是找規律獲得遞推式遞歸
n=1,n=2,n=3是能夠直接獲得的(已知條件);內存
從第四塊開始,放的磚塊有兩種狀況了,要麼橫着放要麼豎着放,string
橫着放有兩種放法,也就是f(2);
豎着放就只有一種放法,f(3);
兩種放法加起來就是f(4);
以此類推,每一個n的方法都是創建在兩種狀況下的,而每種狀況又能夠追溯到最初的已知條件,因此就直接遞歸咯
#include <bits/stdc++.h>
using
namespace
std;
int
f(
int
n)
{
if
(n<=3) //已知條件
return
n;
else
return
f(n-1)+f(n-2); //遞歸式,兩種狀況
問題 I: 倒序輸出 時間限制: 1 Sec 內存限制: 128 MB 提交: 0 解決: 0 201501010119 提交狀態討論版 題目描述 使用遞歸編寫一個程序,逆序輸出一個正整數。例如輸入1234,輸出4321。 輸入 多組輸入,每組輸入一個正整數。 輸出 逆序輸出結果,每一個結果佔一行。 樣例輸入 Copy 12 1234 樣例輸出 Copy 21 4321
#include <bits/stdc++.h> using namespace std; void f(int n) //遞歸函數 { int a; //用來存放數的個位 int s=0; if(n==0) return ; else { a=n%10; //分離個位 cout<<a; f(n/10); //去掉個位,再次遞歸,輸出高位
問題 J: 遞歸求和 時間限制: 1 Sec 內存限制: 128 MB 提交: 0 解決: 0 201501010119 提交狀態討論版 題目描述 使用遞歸編寫一個程序,計算一個正整數中全部數字之和。例如輸入234,輸出9 輸入 多組輸入,每組輸入一個正整數。 輸出 輸出結果,每一個結果佔一行。 樣例輸入 Copy 234 樣例輸出 Copy 9
#include <bits/stdc++.h> using namespace std; int f(int n) {if(n==0) return 0; else { return (n%10+f(n/10)); //分離數的各個位而且加起來而且進入下一次遞歸 } } int main() { int n; while(scanf("%d",&n)!=EOF) { cout<<f(n)<<endl; } return 0; }
} } int main() { int n; while(scanf("%d",&n)!=EOF) { f(n); cout<<endl; } return 0; }
}
int
main()
{
int
n;
while
(
scanf
(
"%d"
,&n)!=EOF)
{
int
s;
s=f(n);
cout<<s<<endl;
}
return
0;
}