IPCP 2005 Northern Preliminary for Northeast North-America &&Fibonacci Numbers

给你一个数n,让你求Fibonacci数的第n项的前四项和后四项,没有八项的只输出前四项。

思路:后四项容易求,两种方法,一种构造矩阵,一种求其周期。。。关键是前四项用到了Fibonacci 公式

代码:

#include<iostream>
#include<cstdio>
#include<string.h>
#include<cmath>
#define  I  (1.0+sqrt(5.0))/2
#define M 10000
using namespace std;
typedef long long L;
typedef struct str
{ L s[2][2];
}Node;
Node a,b,c;
inline void init()
{   a.s[0][0]=0;a.s[0][1]=1;
    a.s[1][0]=1;a.s[1][1]=1;
	b.s[0][0]=1;b.s[0][1]=0;
	b.s[1][0]=0;b.s[1][1]=1;
	c.s[0][0]=1;c.s[0][1]=1;
	c.s[1][0]=0;c.s[1][1]=0;
}
Node ceil(Node p,Node q)
{  Node aa;
   memset(aa.s,0,sizeof(aa.s));
   for(int i=0;i<2;++i)
	   for(int j=0;j<2;++j)
		   for(int t=0;t<2;++t)
			   aa.s[i][j]=(aa.s[i][j]+p.s[i][t]*q.s[t][j])%M;
   return aa;
}
Node doit(int k)
{ 
	Node p=b,q=a;
  while(k)
  { if(1&k) p=ceil(p,q);
       q=ceil(q,q);
	   k=k>>1;
  }
  p=ceil(c,p);//运算不能交换
  return p;
}
int main()
{ 
	int f[40]={0,1};
   for(int i=2;i<40;++i)
	    f[i]=f[i-1]+f[i-2];
   init();
   int n;
   while(~scanf("%d",&n))
   { 
	   if(n<40)
    { printf("%d\n",f[n]);
	    continue;
    }
	   int k=n-2;
	   Node bb=doit(k);
	   double ans=-0.5*(log10(5.0))+n*log10(I);
	   ans-=(int)ans;
	   ans=pow(10.0,ans);
	   while(ans<1000)
		   ans*=10.0;
	   printf("%d...",(int)ans);
	   printf("%04d\n",bb.s[0][1]);//不满足四位的前加0
	   int mm=5;
	   
}return 0;
}

 

你可能感兴趣的:(c,struct,Numbers)