1. Fibonacci数列
无穷数列1,1,2,3,5,8,13,21,34,55,……,称为Fibonacci数列。它可以递归地定义为:
第n个Fibonacci数可递归地计算如下:
int fibonacci(int n)
{
if (n <= 1) return 1;
return fibonacci(n-1)+fibonacci(n-2);
}
- 编写完整的主函数,分别记录利用上述递归函数求第45,46,47,48个Fibonacci数所花费的时间。
#include<stdio.h>
#include<time.h>
long fibonacci(int n)
{
if (n <= 1)
return 1;
return fibonacci(n-1)+fibonacci(n-2);
}
void main()
{
int N,i;
double s;
clock_t start , stop;
for(i=45;i<=48;i++){
start=clock();
fibonacci(i);
printf("第%d个运行时间",i);
stop=clock();
s=(stop-start)/CLK_TCK;
printf(" %lfs\n",s);
}
}
(2)将递归函数改为尾递归,或者是递推函数,求第45,46,47,48个Fibonacci数所花费的时间,观察效率是否得到提高。
#include<stdio.h>
#include<time.h>
long tailfib(int n,int acc1,int acc2) {
if (n < 2) {
return acc1;
}
return tailfib(n-1,acc2,acc1 + acc2);
}
void main()
{
int N,i;
double s;
clock_t start , stop;
for(i=45;i<=48;i++){
start=clock();
printf("%d:%lld",i,tailfib(i,1,1));
stop=clock();
s=(stop-start)/CLK_TCK;
printf(" %lfs\n",s);
}
}
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int a[100];
int n;
int max; //当前最大元素
int f(int n)
{
int min; //当前最小元素
if(n==2) //只有两个元素时,直接求解(最小问题)
{
if(a[n-2]>a[n-1]){
max=a[n-2],min=a[n-1];
}
else{
max=a[n-1],min=a[n-2];
}
return min;
}
else
{
min=f(n-1); //递归找第二大元素
if(a[n-1]>max){
min=max,max=a[n-1]; //找到前面n-1个元素中最大和第二大元素时
}
if(a[n-1]<max&&a[n-1]>min){
min=a[n-1]; //再与第n个元素比较找第二大元素
}
return min; //返回结果
}
}
void random()
{
srand(time(NULL));
for(int i=0;i<n;i++)
{
a[i]=1+rand()%100;
}
}
int main()
{
int s;
printf("请输入元素的个数n:");
scanf("%d",&n);
random();
printf("\n这n个数依次为: ");
for(int j=0;j<n;j++)
printf("%d\t",a[j]);
s=f(n);
printf("\n\n这n个数中第二大元素为:%d\n",s);
return 0;
}
5. 棋盘覆盖问题
在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
算法描述如下:
参数说明:
子棋盘:由棋盘左上角的坐标tr,tc和棋盘大小size表示。
特殊方格:在二维数组中的坐标位置是(dr,dc)。
#include<stdio.h>
int Martrix[100][100];
int tile=0; //整形变量,记录L型骨牌的数量
void chessBoard(int tr, int tc, int dr, int dc, int size) //tr和tc分别是棋盘左上角方格的行号,列号; dr和dc分别代表特殊方格的行号,列号
{
int s,t;
if (1 == size) return;
s = size/2; //分割棋盘
t = ++ tile; //L型骨牌号,初始值为0
if (dr < tr + s && dc < tc +s) //用L型骨牌号覆盖左上角子棋盘
{
chessBoard(tr,tc,dr,dc,s);//特殊方格在此棋盘中
}
else //特殊方格不在此棋盘中用,t号L型骨牌覆盖右下角
{
Martrix[tr+s-1][tc+s-1] = t; //覆盖本子棋盘中的其余方格
chessBoard(tr,tc,tr+s-1,tc+s-1,s);
}
if (dr < tr + s && dc >= tc + s ) //用L型骨牌号覆盖右上角子棋盘
{
chessBoard(tr,tc+s,dr,dc,s); //特殊方格在此棋盘中
}
else //特殊方格不在此棋盘中用,t号L型骨牌覆盖左下角
{
Martrix[tr+s-1][tc+s] = t; //覆盖本子棋盘中的其余方格
chessBoard(tr,tc+s,tr+s-1,tc+s,s);
}
if (dr >= tr + s && dc < tc + s) //用L型骨牌号覆盖右上角棋盘
{
chessBoard(tr+s,tc,dr,dc,s); //特殊方格在此棋盘中
}
else //特殊方格不在此棋盘中,用t号L型骨牌覆盖左下角
{
Martrix[tr+s][tc+s-1] = t; //覆盖本子棋盘中的其余方格
chessBoard(tr+s,tc,tr+s,tc+s-1,s);
}
if (dr >= tr + s && dc >= tc + s) //用L型骨牌号覆盖右上角子棋盘
{
chessBoard(tr+s,tc+s,dr,dc,s); //特殊方格在此棋盘中
}
else //特殊方格不在此棋盘中用t号L型骨牌左上角
{
Martrix[tr+s][tc+s] = t; //覆盖本子棋盘中的其余方格
chessBoard(tr+s,tc+s,tr+s,tc+s,s);
}
}
int main()
{
int size,r,c,row,col;
printf("设置棋盘大小:");
scanf("%d",&size);
printf("\n输入特殊方格位置:(x,y) ");
scanf("%d%d",&row,&col);
chessBoard(0,0,row,col,size);
for (r = 0; r < size; r++)
{
for (c = 0;c<size; c++)
{
printf("%2d ",Martrix[r][c]);
}
printf("\n");
}
return 0;
}