C. Array Destruction (thinking + tree structure + enumeration)

https://codeforces.com/contest/1474/problem/C

Idea: First of all, the condition must be met. The first value is the maximum value. Then follow the idea of ​​the question, and you will find that the answer forms a tree.

Except for 7, 14=11+3; 11=6+5; 6=4+2; 4=3+1; and the left sons are the largest. Therefore, the maximum value is determined, the left son must be a second largest value, and the right son is the difference between the father and the left son. So the question is, how to throw a 7 and how to determine the impact on the result. Enumeration, we enumerate this 7, each time we look up and modify logn in the multiset, and see if the result is satisfied each time.

(I realized that multiset has a function prev to find the maximum value)

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5;
typedef long long LL;
typedef pair<LL,LL>P;
multiset<LL>s;
LL a[maxn];
LL temp;
P ans[maxn];
LL n;
bool solve(LL p){
    LL x=p;
    for(LL k=1;k<=n-1;k++){
        LL mavx=*prev(s.end());
        s.erase(s.find(mavx));
        if(s.find(x-mavx)!=s.end()){
            s.erase(s.find(x-mavx));
            ans[++temp]={mavx,x-mavx};
            x=mavx;
        }
        else break;
    }
    if(temp==n) return 1;
    else return 0;
}
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL t;cin>>t;
  while(t--){
    cin>>n;
    s.clear();
    for(LL i=1;i<=2*n;i++){
        cin>>a[i];
    }
    sort(a+1,a+1+2*n);
    LL res=0;
    ///枚举第一次和最大值搭配的数字
    for(LL i=1;i<=2*n-1;i++){
        s.clear();
        for(LL j=1;j<=n*2;j++){
            s.insert(a[j]);
        }
        s.erase(s.find(a[i]));
        s.erase(s.find(a[n*2]));///最大值
        LL p=a[n*2];
        temp=0;
        ans[++temp]={a[n*2],a[i]};
        if( solve(p)==1){
            break;
        }
    }
    if(temp==n){
        cout<<"YES"<<endl;
        cout<<ans[1].first+ans[1].second<<endl;
        for(LL i=1;i<=temp;i++){
            cout<<ans[i].first<<" "<<ans[i].second<<" "<<endl;
        }
    }
    else cout<<"NO"<<endl;
  }
return 0;
}

 

Guess you like

Origin blog.csdn.net/zstuyyyyccccbbbb/article/details/112859623