hdu_4334,线性查找的学习

http://acm.hdu.edu.cn/showproblem.php?pid=4334

这题开始做的时候,不是O(n^2)*O(logn^3) MLE就是O(n^3)*O(logn^2) TLE了

后来看解题报告都没看懂

幽幽子大神给我讲了下,真的是恍然大悟啊

while(j < cnt1 && k >= 0){
     if(f[j] + g[k] == -tmp){
     flag = 1;
        break;
     }
     if(f[j] + g[k] < 0 - tmp) j ++;
        else k --;
}

对于这一段,开始用最小的加最大的,如果和小于要查找的话,那么说明大的不够用,小的就加,即j++

反之就 k--了

给跪子orz 

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define ll __int64

ll a[210];
ll b[210];
ll c[210];
ll f[202*202];
ll g[202*202];
int n;
int main(){
    int tcase;
    scanf("%d", &tcase);
    while(tcase --){
        scanf("%d", &n);
        memset(f, 0, sizeof f);
        memset(g, 0, sizeof g);
        int cnt1 = 0;
        int cnt2 = 0;
        for(int i = 0; i < n; i ++) scanf("%I64d", a + i);
        for(int i = 0; i < n; i ++) scanf("%I64d", b + i);
        for(int i = 0; i < n; i ++) scanf("%I64d", c + i);
        for(int i = 0; i < n; i ++){
            for(int j = 0; j < n; j ++){
                f[cnt1++] = a[i] + b[j];
            }
        }
        for(int i = 0; i < n; i ++) scanf("%I64d", a + i);
        for(int i = 0; i < n; i ++){
            for(int j = 0; j < n; j ++){
                g[cnt2++] = a[i] + c[j];
            }
        }
        for(int i = 0; i < n; i ++) scanf("%I64d", c + i);

        sort(f, f + cnt1);
        sort(g, g + cnt2);
        sort(c, c + n);

        int flag = 0;
        for(int i = 0; i < n; i ++){
            ll tmp = c[i];
            int j = 0;
            int k = cnt2 - 1;
            while(j < cnt1 && k >= 0){
                if(f[j] + g[k] == -tmp){
                    flag = 1;
                    break;
                }
                if(f[j] + g[k] < 0 - tmp) j ++;
                else k --;
            }
        }
        /*
        for(int i = 0; i < cnt1; i ++){
            for(int j = 0; j < n; j ++){
                ll tmp = 0 - f[i] - c[j];
                if(tmp < g[0] || tmp > g[cnt2-1])continue;
                int l = 0, r = cnt2-1;
                int fl = 0;
                while(l <= r){
                    int mid = l + r >> 1;
                    if(g[mid] == tmp){
                        fl = 1;
                        break;
                    }
                    if(tmp < g[mid])
                        r = mid-1;
                    else if(tmp > g[mid])
                        l = mid+1;
                }
                if(fl){
                    flag = 1;
                    break;
                }
            }
            if(flag) break;
        }
        */
        if(flag)
          puts("Yes");
        else
          puts("No");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/louzhang/p/2620588.html