Codeforces Round #707 (Div. 2) C. Going Home (暴力列舉)
阿新 • • 發佈:2021-03-17
題目連結:https://codeforces.com/contest/1501/problem/C
題目大意:個數,,從中找出四個不同的數,要求,輸出滿足條件的任意的一組
題解:暴力列舉!
我們可以證明若存在四對數,那麼其中一定可以找出四個不同的數,滿足上述條件。
分類討論:
若為的情況,那麼顯然,我們可以選擇作為答案。
若為的情況,那麼顯然我們可以選擇作為答案。
其餘情況,也一定可以從4對數中,選出兩組數滿足條件。
我們可以用圖來證明,我們假設下標為點,若兩個下標的數相加為,我們可以在兩個點中建邊。那麼四條邊,至少需要四個點。當點數為四個點時我們一定可以將四個點分為兩組。當點數超過四個點時,就是上面我們討論的情況。
由此,我們可以暴力列舉和值,對於一個和值,當它出現四次的時候,我們一定可以找到答案。那麼複雜度超過,所以最終複雜度為
程式碼如下:
#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; }