zoukankan      html  css  js  c++  java
  • 1372

    题目链接


    给一个序列,查询可以组成6边形的选择方式。

    思路:
    组成条件是(a_1<a_2<a_3<a_4<a_5<a_6 \,\, AND\,\, a_1+a_2+a_3+a_4+a_5 > a_6)

    想过优化(a_1+a_2+a_3 > a_6-a_5-a_4),枚举(a_3)或者(a_4),但是这样仍是O((n^4)),仍是不行的。

    参考了别人的方法,对于(a_3)(a_4)的选择,只需要选择一个,另一个的范围就已经确定了,这样就变成O((n^3)).

    #include <stdio.h>
    #include <iostream>
    #include <string.h>
    #include <stdlib.h>
    #include <vector>
    #include <algorithm>
    #include <queue>
    #include <map>
    #include <stack>
    #include <string>
    #include <math.h>
    #include <bitset>
    #include <ctype.h>
    using namespace std;
    typedef pair<int,int> P;
    typedef long long LL;
    const int INF = 0x3f3f3f3f;
    const double PI = acos(-1.0);
    const double eps = 1e-9;
    const int N = 1e6 + 5;
    const int mod = 1e9 + 7;
    int n,t,kase=0;
    int c[N],a[N];
    inline int lowbit(int x)
    {
        return x&(-x);
    }
    
    void add(int x, int val)
    {
        while(x < N)
        {
            c[x] += val;
            x += lowbit(x);
        }
    }
    
    int sum(int x)
    {
        int sum = 0;
        while(x)
        {
            sum += c[x];
            x -= lowbit(x);
        }
        return sum;
    }
    
    int main()
    {
        scanf("%d", &t);
        while(t--)
        {
            scanf("%d", &n);
            for(int i = 0; i < n; i++)
                scanf("%d", &a[i]);
            sort(a, a+n);
            memset(c, 0, sizeof(c));
            LL ans = 0;
            for(int k = n-1; k >= 0; k--)
            {
                for(int i = 0; i < k; i++)
                {
                    for(int j = i+1; j < k; j++)
                    {
                        int tmp = a[i]+a[j]+a[k];
                        ans += sum(tmp-1);
                    }
                }
    
                for(int i = k+1; i < n; i++)
                {
                    for(int j = i+1; j < n; j++)
                    {
                        int tmp = a[j]-a[i]-a[k];
                        if(tmp <= 0) tmp = 1;
                        add(tmp, 1);
                    }
                }
            }
            printf("Case %d: %lld
    ", ++kase, ans);
        }
        return 0;
    }
    
  • 相关阅读:
    学习笔记 之《一线架构师实践》
    Java 面试汇总
    C++11移动语义之一(基本概念)
    C++中的RAII介绍
    Qt自定义控件之可伸缩组合框(GroupBox)控件
    redis集群中的增删查改
    redis设置密码
    Linux安装部署FTP服务器
    SSM + MySQL批量删除操作
    SSM
  • 原文地址:https://www.cnblogs.com/Alruddy/p/7496032.html
Copyright © 2011-2022 走看看