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;

}

你可能感兴趣的:(HDU)