https://codeforces.com/contest/1474/problem/C
思路:首先要满足条件第一个值是最大值,然后顺着题目的思路走,会发现答案形成了一颗树。
除了7之外,14=11+3;11=6+5;6=4+2;4=3+1;而且左儿子都是最大的。因此最大值确定了,左儿子一定是一个次大值,右儿子是父亲和左儿子的差。那么问题来了,还有一个7应该怎么扔呢,如何判定对结果的影响呢。枚举,我们枚举这个7,每次在multiset里去logn的查找和修改,看每次结果是否满足。
(才意识到multiset有找最大值的函数prev)
#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;
}