• LightOJ 1372 (枚举 + 树状数组)


    题目

    Link
    输出序列中有多少个组合 {a1,a2,a3,a4,a5,a6}可以构成一个六边形。

    分析

    序列每个数都不相等。
    所以可以设 a1<a2<a3<a4<a5<a6
    把六边形分解为 4 个三角形, 又可以得出
    a1+a2+a3+a4+a5>a6:
    a1+a2+a3>a6a5a4
    a4 固定的情况下, a3[a3,a4)
    所以我们枚举 , 用树状数组维护。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn = 5000000 + 131;
    int C[maxn];
    
    int lowbit(int x) {
        return x &(-x);
    }
    
    int Sum(int x) {
        int ret = 0;
        while(x) {
            ret += C[x];
            x -= lowbit(x);
        }
        return ret;
    }
    
    void Add(int pos) {
        while(pos < maxn) {
            C[pos] ++;
            pos += lowbit(pos);
        }
    }
    
    int Num[105];
    int main() {
        int T;
        scanf("%d",&T);
        for(int kase = 1; kase <= T; ++kase) {
            memset(C, 0, sizeof(C));
            int N;
            scanf("%d",&N);
            for(int i = 0; i < N; ++i)
                scanf("%d",Num+i);
            sort(Num, Num+N);
            int Ans = 0, LowZ = 0;     //小于0的情况用LowZ 统计
            for(int i = N-1; i >= 0; --i) {
                for(int j = 0; j < i; ++j)
                for(int k = j+1; k < i; ++k)
                {
                    int sum = Num[i] + Num[j] + Num[k];
                    Ans += Sum(sum-1);
                    Ans += LowZ;
                }
                for(int j = i + 1; j < N; ++j)
                for(int k = j + 1; k < N; ++k)
                {
                    int sub = Num[k] - Num[j] - Num[i];
                    if(sub > 0) Add(sub);
                    else LowZ ++;
                }
            }
            printf("Case %d: %d
    ",kase, Ans);
        }
        return 0;
    }
  • 相关阅读:
    面试常见问题
    Servlet上传下载
    Java五大框架
    Jquery
    JavaEE
    Html学习
    JavaSE高级
    面向过程基础
    Java开发软件安装及配置
    JAVA的类加载机制和Class类
  • 原文地址:https://www.cnblogs.com/aoxuets/p/5506824.html
Copyright © 2020-2023  润新知