现在的位置: 首页 > 综合 > 正文

西电ACM1197——斐波那契数列

2013年12月07日 ⁄ 综合 ⁄ 共 1913字 ⁄ 字号 评论关闭

原题如下:

Description

   闲的无聊的jxy有一天对斐波那契数列感兴趣了,希望能知道任意一位的斐波那契数,但因为能力不足,不会计算,所以希望聪明的你能帮助他解决这个问题。具体描述见输入说明。

Input
多组数据,输入exit结束
第一行为一个字符串x 代表选择序号
x为exit时,程序退出
x为1时 ,存在第二行 ,第二行为一个数字n ,代表要输出第n个斐波那契数(n<10^18)
x为2时,输出 第1,10,100……,1000000000位斐波那契数,共十个,一行一个
x为其他数字,输出none
x为其他字符,输出error
所有结果对1000000007取余。
每组数据后输出10个-。
Output
输出详见样例。
Sample Input
1
2
1
1
2
8
n
1
2
exit
Sample Output
1
----------
1
----------
1
X
X
X
X
X
X
X
X
X
X(X为那一位的斐波那契数)
----------
none
----------
error
----------
1

其他输出就不管了,主要是计算斐波那契数列的第n项。具体算法见前一文章。

注意哈:在西电ACM的OJ上不支持__int64类型的,所以要用long long 类型,但是我的VC只对__int64能编译过去,所以提交的时候要改成longlong,这个大家会改就行。代码如下:

#include<stdio.h>
#include<string.h>
long long mt[10]={1,55,687995182,517691607,271496360,911435502,918091266,490189494,908460138,21};
typedef struct Matrix
{
	long long a[2][2];
}Matrix;
Matrix E;
void InitE(int size)       //初始化单位矩阵
{
	for(int i=0;i<size;i++)
	{
		for(int j=0;j<size;j++)
			E.a[i][j]=(i==j);
	}
}
Matrix MatrixMul(Matrix a,Matrix b)     //两矩阵相乘   
{
	Matrix c;
	int i,j,k;
	for(i=0;i<2;i++)
	{
		for(j=0;j<2;j++)
		{
			c.a[i][j]=0;
			for(k=0;k<2;k++)
			{
				c.a[i][j] += ((a.a[i][k]%1000000007)*(b.a[k][j]%1000000007));
				c.a[i][j]%=1000000007;
			}
		}
	}
	return c;
}
Matrix MatrixPow(Matrix a,long long n)         //矩阵快速二分求n次幂
{
	Matrix t=E;
	while(n>0)
	{
		if(1&n)     //n是奇数
			t=MatrixMul(t,a);
		a=MatrixMul(a,a);
		n >>= 1;
	}
	return t;
}
int main()
{
	long long n;
	int k,i;
	Matrix matrix,m;
	char num[100000];
	InitE(2);
	while(1)
	{
		k=0;
		scanf("%s",&num);
		if(strcmp(num,"exit")==0)
			break;
		if(strcmp(num,"1")==0)
		{
//			scanf("%I64d",&n);
			scanf("%lld",&n);
			if(n==1||n==2)
				printf("1\n");
			else
			{
				matrix.a[0][0]=1;     //构造初始矩阵
				matrix.a[0][1]=1;
				matrix.a[1][0]=1;
				matrix.a[1][1]=0;
				m=MatrixPow(matrix,n-1);
				printf("%lld\n",(m.a[0][0])%1000000007);
			}
			for(i=0;i<10;i++)
				printf("-");
			printf("\n");
		}
		else if(strcmp(num,"2")==0)
		{
			for(i=0;i<10;i++)
				printf("%lld\n",mt[i]);
			for(i=0;i<10;i++)
				printf("-");
			printf("\n");
		}
		else
		{
			for(i=0;i<strlen(num);i++)
			{
				int c=num[i]-'0';
				if((c<0)||(c>9))
				{
					k=1;
					break;
				}
			}
			if(k==1)
			{
				printf("error\n");
				for(i=0;i<10;i++)
				   printf("-");
		    	printf("\n");
			}
			else
			{
				printf("none\n");
				for(i=0;i<10;i++)
			    	printf("-");
		    	printf("\n");
			}
		}
	}
	return 0;
}

 

抱歉!评论已关闭.