Trouble HDU - 4334

题目网址点击打开链接

    题目大意就是给你5个数组a,b,c,d,e;然后问你是否存在ai+bj+ck+dn+em=0。

    一开始我把5个数组分成了3和2,把后面2个数组合并为一个数组,然后用3个for遍历前面3个数组,然后再用二分找,结果超时了。后来看了题解是把5个数组分成了2,2,1的形式,a和b合成f数组,c和d合成g数组,然后遍历d数组的每一个数,找是否存在fi+gj==dk.不过这个不是简单的3个for来查找。而是用了2个指针初始时一个cnt1指向f数组最小的值,cnt2指向g数组最大的值,每次查找过程是这样的如果f[cnt1]+g[cnt2]==sum就结束了,如果f[cnt1]+g[cnt2]<sum,cnt1++,取f数组里更大的数,如果f[cnt1]+g[cnt2]>sum,cnt2--,取g数组里更大的数。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long t,flag,k1,k2,cnt1,cnt2,n,sum;
    cin>>t;
    while(t--)
    {
        flag=0,k1=0,k2=0;
        long long a[205],b[205],c[205],f[40000+10],g[40000+10];
        cin>>n;
        for(int i=0;i<n;i++)
            scanf("%lld",&a[i]);
        for(int i=0;i<n;i++)
            scanf("%lld",&b[i]);
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                f[k1++]=a[i]+b[j];
        for(int i=0;i<n;i++)
            scanf("%lld",&a[i]);
        for(int i=0;i<n;i++)
            scanf("%lld",&b[i]);
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                g[k2++]=a[i]+b[j];
        for(int i=0;i<n;i++)
            scanf("%lld",&c[i]);
        sort(f,f+k1);
        sort(g,g+k2);
        for(int i=0;i<n;i++)
        {
            flag=0;
            sum=-c[i];
            cnt1=0;
            cnt2=k2-1;
            while(cnt1<k1&&cnt2>=0)
            {
                if((f[cnt1]+g[cnt2])==sum)
                {
                    flag=1;
                    break;
                }
                if(f[cnt1]+g[cnt2]<sum)
                    cnt1++;
                else
                    cnt2--;
            }
            if(flag)
                break;


        }
        if(flag)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40642465/article/details/81002530