zoukankan      html  css  js  c++  java
  • uva1152 4 Values whose Sum is 0

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=100977#problem/C

    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    #define PII pair<int,int>
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=16000100;
    const int INF=(1<<29);
    
    int n;
    ll A[maxn],B[maxn],C[maxn],D[maxn];
    ll a[maxn],b[maxn];
    int cnt_a,cnt_b;
    int cnt;
    
    int bin(int l,int r,ll val)
    {
        while(l<r){
            int m=(l+r)>>1;
            //if(val==0) cout<<l<<" "<<r<<" "<<m<<endl;
            if(b[m]==val) return m;
            if(b[m]<val) l=m+1;
            else r=m;
        }
        //if(val==0) cout<<"l="<<l<<endl;
        if(b[l]==val) return l;
        if(b[r]==val) return r;
        return -1;
    }
    
    int main()
    {
        freopen("in.txt","r",stdin);
        int T;cin>>T;
        while(T--){
            scanf("%d",&n);
            REP(i,1,n) scanf("%lld%lld%lld%lld",&A[i],&B[i],&C[i],&D[i]);
            sort(A+1,A+n+1);sort(B+1,B+n+1);sort(C+1,C+n+1);sort(D+1,D+n+1);
            cnt_a=cnt_b=0;
            REP(i,1,n){
                REP(j,1,n){
                    a[++cnt_a]=A[i]+B[j];
                    b[++cnt_b]=C[i]+D[j];
                }
            }
            //REP(i,1,cnt_b) cout<<b[i]<<endl;
            sort(a+1,a+cnt_a+1);sort(b+1,b+cnt_b+1);
            //REP(i,1,cnt_a) cout<<a[i]<<" ";cout<<endl;
            //REP(i,1,cnt_b) cout<<b[i]<<" ";cout<<endl;
            cnt=0;
            REP(i,1,cnt_a){
                int k=bin(1,cnt_b,-a[i]);
                if(k==-1) continue;
                //cout<<"ai="<<a[i]<<" k="<<k<<endl;
                REP(j,k,cnt_b){
                    if(b[j]==b[k]) cnt++;
                    else break;
                }
                for(int j=k-1;j>=1;j--){
                    if(b[j]==b[k]) cnt++;
                    else break;
                }
            }
            cout<<cnt<<endl;
            if(T) puts("");
        }
        return 0;
    }
    
    /**
    题意:
        给4个数集,从每个数集中取出任意一个数,使取出的4个数的和为0,求方案数。每个数集大小n<=4000.
    分析:
        把前两个数集求和,后两个数集也求和,得到新的大小为n*n数集的两个数集,枚举第一个数集,二分查找第二个数集。
    类型:
        二分,优化。
    注意事项:
        二分。。。。l<r的二分方式查找一个数时必须在跳出循环时特判l==r的情况,注意不要爆long long。
    坑点:
        格式啊格式。。。。
    总结:
        
    */
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    P1144 最短路计数
    P2966 [USACO09DEC]牛收费路径Cow Toll Paths
    P2419 [USACO08JAN]牛大赛Cow Contest
    P1462 通往奥格瑞玛的道路
    P1346 电车
    P1339 [USACO09OCT]热浪Heat Wave
    P1418 选点问题
    P1330 封锁阳光大学
    P1182 数列分段Section II
    P2661 信息传递
  • 原文地址:https://www.cnblogs.com/--560/p/5006195.html
Copyright © 2011-2022 走看看