Fibonacci的【兔子數列】和 變形約瑟夫環的【狐狸找兔子】,臺階問題
1,有一對兔子,從出生後第3個月起每個月都生一對兔子,小兔子長到第三個月後每個月又生一對兔子,假如兔子都不死,問每個月的兔子總數爲多少? 兔子的規律爲數列1,1,2,3,5,8,13,21....
#include<stdio.h>
int main(void)
{
long f1,f2;
int i, k ;
f1=f2=1;
scanf("%d",&k)==1;
for(i=1;i<=k;i++)
{
printf("%15ld %15ld",f1,f2);
if(i%2==0) printf("\n");/*控制輸出,每行四個*/
f1=f1+f2; /*前兩個月加起來賦值給第三個月*/
f2=f1+f2; /*前兩個月加起來賦值給第四個月*/
}
return 0;
}
2.圍繞着山頂有10個圓形排列的洞,狐狸要吃兔子,兔子說:“可以,但必須先找到我,我就藏身於這十個洞中的某個洞。你從1號洞找,下次隔1個洞(即3號洞)找,第三次隔2個洞(即6號洞)找,再隔3個…以後在這個圓圈中如此類推,次數不限。”但狐狸從早到晚進進出出了1000次,仍沒有找到兔子。
問兔子究竟藏在哪個洞裏?
第一種算法,簡潔明瞭,容易理解。
#include <stdio.h>
/* flag[0] 標記的是10號洞
1表示狐狸進過的洞,0表示
狐狸沒進過的洞
結果是兔子可能在:2、4、7或9號洞
*/
void main()
{
int i=0;
int flag[10]={0};
for(i=1;i<1001;i++)
{
flag[((i*(i+1))/2)%10]=1;
}
for(i=0;i<10;i++)
{
printf("%d:%d\n",i,flag[i]);
}
}
第二種方法,其實原理一樣
#include<stdio.h>
int main()
{
int hole[10]={1,2,3,4,5,6,7,8,9,10};
int i,j=0,index;
for(i=0;i<1000;i++)
{
j=j+i+2;
index=j%10;
hole[index]=1;
}
for(i=0;i<10;i++)
{
if(hole[i]!=1)
printf("rabbit is at the hole %d\n",hole[i]);
}
return 0;
}
3,一個臺階總共有n級,如果一次可以跳1級,也可以跳2級。求總共有多少種跳法,並分析算法的時間複雜度。
答:用一個函數f(n)來表示n級臺階總的跳法。
1、只有1個臺階,則f(1) = 1;
2、有2個臺階,則f(2) = 2;
3、當有n個臺階時,如果第一次跳1級,有f(n-1)種跳法,如果第一次跳2級,有f(n - 2)種跳法,即f(n) = f(n-1) + f(n-2)。
即爲Fibonacci序列。
#include "stdafx.h"
#include <iostream>
using namespace std;
//循環
int TotalStep(int n)
{
if (n <= 0)
{
return 0;
}
else if (1 == n || 2 == n)
{
return n;
}
int first = 1;
int second = 2;
int total = 0;
for (int i = 3; i <= n; i++)
{
total = first + second;
first = second;
second = total;
}
return total;
}
//遞歸
int RecurTotalStep(int n)
{
if (n <= 0)
{
return 0;
}
else if (n == 1 || n == 2)
{
return n;
}
else
{
return RecurTotalStep(n - 1) + RecurTotalStep(n - 2);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
cout<<TotalStep(20)<<endl;
cout<<RecurTotalStep(20)<<endl;
return 0;
}