1. 程式人生 > 其它 >Codeforces Round #707 (Div. 2) C. Going Home (暴力列舉)

Codeforces Round #707 (Div. 2) C. Going Home (暴力列舉)

題目連結:https://codeforces.com/contest/1501/problem/C

題目大意:n(1<=n<=200000)個數,a[1],a[2]...a[n](1<=a[i]<=2.5*10^6),從中找出四個不同的數x,y,z,w,要求a[x]+a[y]=a[z]+a[w],輸出滿足條件的任意的一組x,y,z,w

題解:暴力列舉!

我們可以證明若存在四對數a[x1]+a[y1]=a[x2]+a[y2]=a[x3]+a[y3]=a[x4]+a[y4],(xi\neq yi),那麼其中一定可以找出四個不同的數,滿足上述條件。

分類討論:

若為(x,y1),(x,y2),(x,y3),(x,y4)的情況,那麼顯然a[y1]=a[y2]=a[y3]=a[y4],我們可以選擇(y1,y2),(y3,y4)作為答案。

若為(x,y1),(x,y2),(x,y3),(z,w)的情況,那麼顯然我們可以選擇(x,y1),(z,w)作為答案。

其餘情況,也一定可以從4對數中,選出兩組數滿足條件。

我們可以用圖來證明,我們假設下標為點,若兩個下標的數相加為s,我們可以在兩個點中建邊。那麼四條邊,至少需要四個點。當點數為四個點時我們一定可以將四個點分為兩組。當點數超過四個點時,就是上面我們討論的情況。

由此,我們可以O(n^2)暴力列舉和值,對於一個和值C,當它出現四次的時候,我們一定可以找到答案。那麼複雜度超過O(4*C),所以最終複雜度為O(min(n^2,C))

程式碼如下:

#include<bits/stdc++.h>

using namespace std;
const int nn =210000;
const int inff = 0x3fffffff;
const double eps = 1e-8;
typedef long long LL;
const double pi = acos(-1.0);
const LL mod = 1000000007;
int n;
int a[nn];
vector<pair<int,int>> sum[nn*30];
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    bool ans=false;
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            int v=a[i]+a[j];
            sum[v].push_back(make_pair(i,j));
            if(sum[v].size()>=4)
            {
                cout<<"YES"<<endl;
                for(int k=0;k<int(sum[v].size());k++)
                {
                    if(sum[v][k].first!=i&&sum[v][k].first!=j)
                    {
                        if(sum[v][k].second!=i&&sum[v][k].second!=j)
                        {
                            ans=true;
                            cout<<sum[v][k].first<<" "<<sum[v][k].second<<" "<<i<<" "<<j<<endl;
                        }
                    }
                    if(ans)
                        break;
                }
                if(!ans)
                {
                    ans=true;
                    if(sum[v][0].first == i)
                    {
                        cout<<sum[v][0].second<<" "<<sum[v][1].second<<" "<<sum[v][2].second<<" "<<j<<endl;
                    } else {
                        cout<<sum[v][0].first<<" "<<sum[v][1].first<<" "<<sum[v][2].first<<" "<<i<<endl;
                    }
                }
            } else {
                for(int k=0;k<int(sum[v].size());k++)
                {
                    if(sum[v][k].first!=i&&sum[v][k].first!=j)
                    {
                        if(sum[v][k].second!=i&&sum[v][k].second!=j)
                        {
                            ans=true;
                            cout<<"YES"<<endl;
                            cout<<sum[v][k].first<<" "<<sum[v][k].second<<" "<<i<<" "<<j<<endl;
                        }
                    }
                    if(ans)
                        break;
                }
            }
            if(ans)
                break;
        }
        if(ans)
            break;
    }
    if(!ans)
        cout<<"NO"<<endl;
    return 0;
}