标题 noj10k阶斐波那契数列
题目
首先,我们需要明白k阶斐波那契数列的定义,它不是我们之前熟知的那种斐波那契数列,其定义如下:
K阶斐波那契数列的前K-1项均为0,第k项为1,以后的每一项都是前K项的和
比如二阶斐波那契数列:0、1、1、2、3、5、8、13、21、34、…
三阶则是:0、0、1、1、2、4、7…
笔者采用循环队列中的链式存储结构解答(网上也有诸多大佬的其他解法)
话不多说,上代码:
#include <stdio.h>
#include <stdlib.h>
//递归函数,计算k阶斐波那契数列
int fib(int n,int k)//n为项,k为阶数
{
if(n<=k-1) return 0;//前k-项为0
if(n==k) return 1;//第k项为1
else
{
int num=0;
for(int i=0;i<k;i++,n--)
{
int t=fib(n-1,k);
num+=t;
}
return num;
}
}
//结点
typedef struct Node
{
int val;
struct Node *next;
}Node,*ListNode;
//队列
typedef struct queue
{
ListNode front;
ListNode rear;
}LinkQueue;
//初始化队列
void InitQueue(LinkQueue *a)
{
if(!a) return;
a->front=a->rear=(ListNode)malloc(sizeof(Node));
a->front->next=NULL;
}
//入队
void AddNode(LinkQueue *a,int n)
{
if(!a) return;
ListNode p=(ListNode)malloc(sizeof(Node));
p->val=n;
p->next=a->front;
a->rear->next=p;
a->rear=p;
}
//判满 1为满
int JudgeFull(LinkQueue *s,int n)
{
int i=0;
ListNode p=s->front->next;
while(p!=s->front)
{
i++;
p=p->next;
}
if(i==n) return 1;
else return 0;
}
//出队
int DeQueue(LinkQueue *s)
{
ListNode p;
int m;
if(s->front==s->rear){printf("队列已空");}
else
{
p=s->front->next->next;
m=p->next->val;
s->front->next=p;
}
return m;
}
//输出
void PrintQueue(LinkQueue *s)
{
ListNode p=s->front->next;
while(p!=s->front)
{
printf("%d ",p->val);
p=p->next;
}
}
int main()
{
int max,k;
scanf("%d%d",&max,&k);
int i=1; //i记录斐波那契数列项数 起始为f(0),f(1)
LinkQueue a;
InitQueue(&a);
//这里可能有一点问题,理解成把0项去掉
AddNode(&a,1);
AddNode(&a,1);
int num=0;
//由于之前WA多次,以为是特殊数据问题
if(k==0)
{
return 0;
}
if(k==1)//直接算就行
{
int t=0;
while(t<=max)
{
num=fib(i,k);
t=fib(i+1,k);
i++;
}
printf("%d",num);
return 0;
}
while(1)
{
num=fib(i,k);
if(num>max)//如果大于了,就输出
{
PrintQueue(&a);
break;
}
else
{
int temp=JudgeFull(&a,k);
if(temp==1)//队满,则更新数据
{
DeQueue(&a);
AddNode(&a,num);
}
else//否则继续添加节点
{
AddNode(&a,num);
}
}
i++;
}
return 0;
}
希望大家多多批评指正~~