Problem
In this problem, you have to find the last three digits before the decimal point for the number (3 + √5)n.
For example, when n = 5, (3 + √5)5 = 3935.73982... The answer is 935.
For n = 2, (3 + √5)2 = 27.4164079... The answer is 027.
Input
The first line of input gives the number of cases, T. T test cases follow, each on a separate line. Each test case contains one positive integer n.
Output
For each input case, you should output:
Case #X: Ywhere X is the number of the test case and Y is the last three integer digits of the number (3 + √5) n. In case that number has fewer than three integer digits, add leading zeros so that your output contains exactly three digits.
Limits
1 <= T <= 100
Small dataset
2 <= n <= 30
Large dataset
2 <= n <= 2000000000
Sample
题解:留着,等会写。先贴代码。不知道为什么提交不上去。运用了二项式原理。
因为是求(3+根号5)的n次方。我们可以添加一个(3-根号5)的n次方。其值远小于1,然后两者相加得s=a+b根号5.太麻烦了,不想写了。https://code.google.com/codejam/contest/32016/dashboard#s=a&a=2
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <list>
#include <vector>
using namespace std;
#define DeBug
struct Mx
{
int a[3][3];
}f,k;
void Init()
{
k.a[1][1]=1;
k.a[2][1]=0;
k.a[1][2]=0;
k.a[2][2]=1;
}
Mx mul(Mx x,Mx y)
{
Mx z;
int i,j,l;
for (i=1;i<=2;i++)
for (j=1;j<=2;j++)
{
z.a[i][j]=0;
for (l=1;l<=2;l++)
z.a[i][j]=(z.a[i][j]+x.a[i][l]*y.a[l][j]) % 1000;
}
return z;
}
Mx ksm(Mx f,int n)
{
if (n==1) return f;
if (n % 2==0)
{
Mx k1=ksm(f,n/2);
return mul(k1,k1);
}
else
return mul(f,ksm(f,n-1));
}
int main()
{
#ifdef DeBug
freopen("C-large-practice.in","r",stdin);
freopen("output.out","w",stdout);
#endif
int T,n;
scanf("%d",&T);
f.a[1][1]=3;f.a[1][2]=5;
f.a[2][1]=1;f.a[2][2]=3;
for (int cas=1;cas<=T;cas++)
{
scanf("%d",&n);
Init();
Mx ans=ksm(f,n);
printf("#Case %d: %03d\n",cas,(2*ans.a[1][1]+999) % 1000);
}
return 0;
}