hdu 3083很锻炼人的一道推公式题
不知道大牛们有没有简洁的方法,反正我是一步一步慢慢推公式做出来的。居然推了一下午啊,囧。。。真是老了不中用了。。。
其实推完后再整理整理,发现还是挺简单的,其实就是几个数列而已
数列①1, 2, 3, 4, 5, 6, 7, 8, 。。。
数列②1, 3, 6, 10, 15, 21, 28, 36。。。
数列③1, 4, 10, 20, 35, 56, 。。。
数列④1, 5, 15, 35, 70
数列⑤3, 10, 21, 36,。。。
数列⑥1, 6, 15, 28, 。。。
我主要是把问题进行分解,三角形个数=正放三角形个数+倒放三角形个数
正放三角形个数=边长为1的正放三角形个数+边长为2的正放三角形个数+。。。
而边长为k的正放三角形个数为合法的每一层的边长为k的正放三解形的个数
而每一层的边长为k的正放三解形的个数正好是数列①,所以正放三角形个数正好是数列③
倒立的三角形个数稍难算,得分奇偶。当n为奇数时,是数列⑤的前n项和数列;当n为偶数时是数列⑥的前n项和数列,当然,⑤和⑥分别是数列②的偶数项和奇数项构成的子数列。
菱形个数最好算,就是倒立三角形个数*3
算平行四边形个数的时候,我是先只考虑两条边平行大三角形底边,另两边平行于大三角形左边的平行四边行,显然,总的平形四边形数为这个数的3倍
而刚才说的这种平行四边形的个数正好是数列④
把这几个公式整理成通项的形式就可以计算了,最后再考虑一些特殊情况,还有就是计算的时候时时取模防止溢出,就OK了,我是1Y的,哈哈~~~
/* * hdu3083/win.cpp * Created on: 2012-7-15 * Author : ben */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <queue> #include <set> #include <map> #include <stack> #include <string> #include <vector> #include <deque> #include <list> #include <functional> #include <numeric> #include <cctype> using namespace std; const int MOD = 20091226; typedef long long LL; inline int getS(LL n) { LL mod = MOD * 6; LL ret = (n % mod) * ((n + 1) % mod); ret %= mod; ret *= (n + 2) % mod; ret %= mod; ret /= 6; return (int)ret; } inline int getX(LL n) { if(n <= 1) { return 0; } int mod = MOD * 24; LL ret = (n + 1) % mod; if(n % 2 == 1) { ret = (((2 * ret - 3) * ret) % mod - 2) * ret; }else { ret = (n % mod) * ((n + 2) % mod); ret %= mod; ret *= (2 * n - 1) % mod; } ret %= mod; ret /= 24; return ret; } inline int getP(LL n) { if(n < 1) { return 0; } int mod = MOD * 8; LL ret = n % mod; ret = ((((ret * (ret + 1))% mod) * (ret + 2))% mod) * (ret + 3); ret %= mod; ret /= 8; return ret; } int main() { #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); #endif int n; LL t, d, p, s, x; while(scanf("%d", &n) == 1) { s = getS(n); x = getX(n); t = s + x; d = 3 * x; p = getP(n - 1); printf("Triangle: %d\n", t % MOD); printf("Diamond: %d\n", d % MOD); printf("Parallelogram: %d\n", p % MOD); } return 0; }