#include<stdio.h>
#include<iostream>
using namespace std;
const int N = 12;//定義所求月份
/*著名意大利數學家Fibonacci曾提出一個問題:有一對小兔子,從出生後第3個月起每個月都生一對兔子。
小兔子長到第3個月後每個月又生一對兔子。按此規律,假設沒有兔子死亡,第一個月有一對剛出生的小兔子,
問第n個月有多少對兔子?*/
//總體思路是f(n)=f(n-2)+f(n-1) 即本月的兔子=本月新出生兔子+以前留下的老兔子
//因爲2個月之前的兔子此時全部具有繁殖能力 因此新兔子的數量=f(n-2)
//又因爲前一個月的兔子全部活下來了 因此本月的老兔子數量=f(n-1)
void RabbitBreeding1(int n);
void RabbitBreeding2(int n);
void RabbitBreeding3(int n);
//求最大公約數
//1.輾轉相除法:取兩個數中最大的數做除數,較小的數做被除數,用最大的數除較小數,
//如果餘數爲0,則較小數爲這兩個數的最大公約數,
//如果餘數不爲0,用較小數除上一步計算出的餘數,直到餘數爲0,則這兩個數的最大公約數爲上一步的餘數。
void GreatestCommonDivisor1();
//2.相減法:取兩個數中的最大的數做減數,較小的數做被減數,用最大的數減去小數,
//如果結果爲0,則被減數就是這兩個數的最大公約數,
//如果結果不爲0,則繼續用這兩個數中最大的數減較小的數,直到結果爲0,則最大公約數爲被減數。
void GreatestCommonDivisor2();
//3.窮舉法:將兩個數作比較,取較小的數,以這個數爲被除數分別和輸入的兩個數做除法運算,
//被除數每做一次除法運算,值減少1,直到兩個運算的餘數都爲0,則該被除數爲這兩個數的最大公約數。
void GreatestCommonDivisor3();
int main ()
{
RabbitBreeding1(N);
RabbitBreeding2(N);
RabbitBreeding3(N);
GreatestCommonDivisor1();
GreatestCommonDivisor2();
GreatestCommonDivisor3();
}
//c = a + b; a = b; b = c;做數據的遷移 每次循環只進行了一個月的遞推 因此總共需要進行n次 ab代表1月和2月 因此循環部分爲3->n
void RabbitBreeding1(int n)
{
int i, a = 1, b = 1, c = 0;
cout << "1月:" << a << endl << "2月:" << b << endl;
for(i = 3; i <= n; i++)
{
c = a + b;
a = b;
b = c;
cout << i << "月:" << c << endl;
}
cout << "\n第" << n << "月共有兔子:" << c << endl;
}
//c=a+b; a=b+c; b=c+a; 構造循環不變式 這樣循環一次遞推3步 循環次數減少 爲n/3次
void RabbitBreeding2(int n)
{
int i, a = 1, b = 1, c = 0;
for(i = 1; i <= n / 3; i++)
{
c = a + b;
a = b + c;
b = c + a;
}
cout << "\n\n第" << n << "月共有兔子:" << c << endl;
}
//可以無需引入第三個變量 a=a+b;b=a+b; 此時循環一次遞推2步
void RabbitBreeding3(int n)
{
int i, a = 1, b = 1;
for(i = 1; i <= (n - 2) / 2 ; i++)//因爲ab有初始值 已經代表了2個月 因此所求月份是n-2 同時因爲每次遞推2步 因此/2
{
a = a + b;
b = b + a;
}
cout << "\n\n第" << n << "月共有兔子:" << b << endl;
}
//輾轉相除法
void GreatestCommonDivisor1()
{
int a = 36, b = 5;//求a,b的最大公約數
int prea = a, preb = b;
int c = a % b;
while(c)
{
a = b;
b = c;
c = a % b;
}
cout << endl << prea << "和" << preb << "最大公約數是:" << b <<endl;
}
//相減法
void GreatestCommonDivisor2()
{
int a = 36, b = 5;//保證a>b;
int prea = a, preb = b;
int c = a - b;
while(c)
{
a = b > c ? b : c;//保證a>b;
if(a == b)//被減數>減數>差 此時a,b的值依次後延 即a=b, b=c;
b = c;
//不滿足if條件說明b<c此時只需要a=c即可滿足被減數>減數
c = a - b;
}
cout << endl << prea << "和" << preb << "最大公約數是:" << b <<endl;
}
//窮舉法
void GreatestCommonDivisor3()
{
int a = 36, b = 5;
int mins = a > b ? b : a;//求出兩數中較小的那個
while(a % mins || b % mins)//兩個運算的餘數都不爲0 (德摩根)
{
mins--;
}
cout << endl << a << "和" << b << "最大公約數是:" << mins <<endl;
}