zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    java分解质因数
    GUID全局唯一标识符
    Oracle-教师信息表(Teacher)
    Oracle-成绩表(Score)
    Oracle-建表course
    Oracle-建表student
    输入输出-复制
    Map
    哈希
    链表
  • 原文地址:https://www.cnblogs.com/moonbay/p/2592736.html
Copyright © 2011-2022 走看看