BZOJ 1002 - 奇妙的题目 + 高精度

这道题有很多奇妙的方法可以搞。。最科学的当然是基尔霍夫矩阵(按照传统,“我也不知道是什么东西”),详见VFK教主的博客;还有乱七八糟的找规律,网上遍地都是。。我就把这题当作高精度练习题了。。

(你为什么又抄黄学长模板!?。。

 

// BZOJ 1002

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

 const int maxN=100+5, N=100+5;

 #define rep(i,a,b) for (int i=a; i<=b; i++)
 #define dep(i,a,b) for (int i=a; i>=b; i--)
 #define read(x) scanf("%d", &x)
 #define fill(a,x) memset(a, x, sizeof(a))

 struct Big_int {
 	int len, a[maxN];  // 1..len -> 个 十 百 ...
 	void init() { len=0; fill(a, 0); }
 } f[N];

 int n;

 // 高精度处理流程:先把数搞出来,然后作进退位,最后处理最高位
 Big_int mul(Big_int a, int k) {  // 高精*单精
 	rep(i,1,a.len) a.a[i]*=k;
 	rep(i,1,a.len) {
 		a.a[i+1]+=a.a[i]/10;
 		a.a[i]%=10;
 	}
 	while (a.a[a.len+1]!=0) a.len++;
 	return a;
 }

 Big_int sub(Big_int a, Big_int b) { // 高精-高精(顺便+2)
    a.a[1]+=2;
 	int j=1;
 	while (a.a[j]>=10) a.a[j+1]++, a.a[j]%=10, j++; // 处理进位,勿忘j++!
 	rep(i,1,a.len) {
 		a.a[i]-=b.a[i];
 		if (a.a[i]<0) { a.a[i]+=10; a.a[i+1]--; }
 	}
 	while (a.a[a.len]==0) a.len--;
 	return a;
 }
 
int main()
{
    read(n);
    f[1].a[1]=1; f[2].a[1]=5;
    f[1].len=f[2].len=1;

    rep(i,3,n) f[i]=sub(mul(f[i-1], 3), f[i-2]);

    dep(i,f[n].len,1) printf("%d", f[n].a[i]);
    puts("");
	
	return 0;
}


 

posted @ 2015-12-29 00:10  Armeria  阅读(156)  评论(0编辑  收藏  举报