(code jam)Problem C. Numbers

本文介绍了一种计算形式为(3+√5)^n的数在小数点前最后三位整数的方法。通过矩阵快速幂算法解决此问题,并提供了完整的代码实现。适用于小数据集(n≤30)和大数据集(n≤2000000000)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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, TT 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: Y
where  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


Input 
 

Output 
 
2
5
2
Case #1: 935
Case #2: 027

题解:留着,等会写。先贴代码。不知道为什么提交不上去。运用了二项式原理。

因为是求(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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值