zoukankan      html  css  js  c++  java
  • UVA 1152 4 Values Whose Sum is Zero 和为0的4个值 (中途相遇)

    摘要:中途相遇。对比map,快排+二分查找,Hash效率。

    n是4000的级别,直接O(n^4)肯定超,所以中途相遇法,O(n^2)的时间枚举其中两个的和,O(n^2)的时间枚举其他两个的和的相反数,然后O(logN)的时间查询是否存在。

    首先试了下map,果断TLE

    //TLE
    #include<cstdio>
    #include<algorithm>
    #include<map>
    using namespace std;
    
    const int maxn = 4001;
    int data[4][maxn];
    
    
    map<int,int> cnt;
    
    int main()
    {
    
        int T ; scanf("%d",&T);
        int *A = data[0], *B = data[1], *C = data[2],*D = data[3];
        map<int,int>::iterator it;
        while(T--){
            int n; scanf("%d",&n);
            for(int i = 0; i < n; i++){
                scanf("%d%d%d%d",A+i,B+i,C+i,D+i);
            }
    
            for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++){
                cnt[A[i]+B[j]]++;
            }
    
            int ans = 0;
            for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++){
                int tmp = -C[i]-D[j];
                it = cnt.find(tmp);
                if(it!=cnt.end()) ans += it->second;
            }
            printf("%d
    ",ans);
            if(T) putchar('
    ');
        }
    
        return 0;
    }
    map,TLE

    然后改成了快排+二分查找,4920ms

    // runtime 4920ms
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 4001;
    int data[4][maxn];
    int vec[maxn*maxn];
    
    int _lower_bound(int *A,int L,int R,int v)
    {
        int m;
        while(L<R){
            m = (L+R)>>1;
            if(A[m]>=v) R = m;
            else L = m+1;
        }
        return L;
    }
    
    int _upper_bound(int *A,int L,int R,int v)
    {
        int m;
        while(L<R){
            m = (L+R)>>1;
            if(A[m]>v) R = m;
            else L = m+1;
        }
        return L;
    }
    
    
    int main()
    {
    
        int T ; scanf("%d",&T);
        int *A = data[0], *B = data[1], *C = data[2],*D = data[3];
        while(T--){
            int n; scanf("%d",&n);
            for(int i = 0; i < n; i++){
                scanf("%d%d%d%d",A+i,B+i,C+i,D+i);
            }
    
            int sz = 0;
            for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++){
                vec[sz++] = A[i]+B[j];
            }
            sort(vec,vec+sz);
    
            int ans = 0;
            for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++){
                int tmp = -(C[i]+D[j]);
                ans +=  _upper_bound(vec,0,sz,tmp) - _lower_bound(vec,0,sz,tmp);
            }
            printf("%d
    ",ans);
            if(T) putchar('
    ');
        }
    
        return 0;
    }
    快拍+二分,4920ms

    实际上没有必要每次二分查找,用两个指针,两边都从最小的数开始比较。

    快排+计数,2832ms

    #include<cstdio>
    #include<algorithm>
    #include<map>
    using namespace std;
    typedef pair<int,int> pii;
    #define fi first
    #define se second
    const int maxn = 4001;
    int data[4][maxn];
    
    pii cnt1[maxn*maxn];
    pii cnt2[maxn*maxn];
    int vec[maxn*maxn];
    
    int main()
    {
        int T ; scanf("%d",&T);
        int *A = data[0], *B = data[1], *C = data[2],*D = data[3];
        while(T--){
            int n; scanf("%d",&n);
            for(int i = 0; i < n; i++){
                scanf("%d%d%d%d",A+i,B+i,C+i,D+i);
            }
            int sz = 0;
            for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++){
                vec[sz++] = A[i]+B[j];
            }
            sort(vec,vec+sz);
            int len1 = 0;
            cnt1[len1] = pii(vec[len1],1);
            for(int i = 1; i < sz; i++){
                if(vec[i] == cnt1[len1].fi) cnt1[len1].se++;
                else { cnt1[++len1].fi = vec[i]; cnt1[len1].se = 1; }
            }
            sz = 0;
            for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++){
                vec[sz++] = -C[i]-D[j];
            }
            sort(vec,vec+sz);
            int len2 = 0;
            cnt2[len2] = pii(vec[len2],1);
            for(int i = 1; i < sz; i++){
                if(vec[i] == cnt2[len2].fi) cnt2[len2].se++;
                else { cnt2[++len2].fi = vec[i]; cnt2[len2].se = 1; }
            }
    
            int p = 0,q = 0,ans = 0;
            while(p<=len1&&q<=len2){
                if(cnt1[p].fi == cnt2[q].fi){
                    ans += cnt1[p++].se*cnt2[q++].se;
                }else if(cnt1[p].fi>cnt2[q].fi) q++;
                      else p++;
            }
            printf("%d
    ",ans);
            if(T) putchar('
    ');
        }
    
        return 0;
    }
    快排+计数

    还有Hash表,写挂了,待补。。。

  • 相关阅读:
    ASP.NET MVC & EF 构建智能查询 二、模型的设计与ModelBinder
    ASP.NET MVC & EF 构建智能查询 一、智能查询的需求与设计
    在ASP.NET中自动合并小图片并使用CSS Sprite显示出来
    Entity Framework with MySQL Provider 更新行数为0的Bug
    为ASP.NET MVC 2.0添加Razor模板引擎 (on .NET4)
    ASP.NET MVC 2.0 in Vs2010 :使用C# 4.0中使用动态类型来传递ViewData
    问题贴
    Visual Studio 2010 RC 下安装ASP.NET MVC 2.0 RTM
    Microsoft Ajax CDN与Google Ajax CDN 你来试试哪个快
    ASP.NET MVC & EF 构建智能查询 三、解析QueryModel
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4692021.html
Copyright © 2011-2022 走看看