トピックリンク
題名:
2n個の数値のシーケンスが与えられた場合、最初に任意のx値を選択し、シーケンス内で2つの数値を見つけて、これら2つの数値の合計がxに等しくなるようにすることができます。次に、これら2つの数値を削除し、xをこれら2つの数値の最大値に等しくします。シーケンス全体が削除されるまで。
質問:シーケンスを完全に削除できるように、xの初期値を見つけてください。完全に削除できない場合は、NOを出力してください。
アイデア:
各操作が完了すると、xは削除された2つの数値の最大値に等しくなるためです。したがって、すべての番号を削除できるようにするには、削除された番号の各ペアに、現在のシーケンスの最大値が含まれている必要があります。
したがって、現在のシーケンスで最大の値を使用する必要があるたびに、後で使用しないと使用できなくなり、削除されていない数値が存在するためです。番号は、シーケンス内で最大の番号である必要があります。他の番号は自由に選択できますが、条件が満たされているかどうかを後で判断する必要があります。
この場合、各xが実行可能かどうかを維持および判断する必要があり、(sum-maximum)が存在するかどうかをすばやく見つけることができます。継続する更新合計がある場合、存在しない場合は実行不可能です。
この場所はマルチセットを使用する必要があります。要素をすばやく見つけて削除できます。
#include <set>
#include <map>
#include <queue>
#include <string>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
typedef pair<ll,ll> pii;
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl;
#define rep(i,n) for(int i=0;i<(n);++i)
#define repi(i,a,b) for(int i=int(a);i<=(b);++i)
#define repr(i,b,a) for(int i=int(b);i>=(a);--i)
const int maxn=2e5+1010;
#define inf 0x3f3f3f3f
#define sf scanf
#define pf printf
const int mod=998244353;
const int MOD=10007;
inline int read() {
int x=0;
bool t=false;
char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
/*
vector<ll> m1;
vector<ll> m2;
priority_queue<ll , vector<ll> , greater<ll> > mn;//上 小根堆 小到大
priority_queue<ll , vector<ll> , less<ll> > mx;//下 大根堆 大到小
*/
map<ll,ll>mp;
map<ll,ll>mpp;
multiset<ll> s,t;
vector<ll> ans;
ll n,m,u,d,r,l;
ll a[maxn];
bool check1(ll sum){
ans.clear();
t=s;
multiset<ll>::iterator it1,it2;
while(!t.empty()){
it1=t.end();
it1--;
ll now=*it1;
t.erase(it1);
it2=t.find(sum-now);
if(it2!=t.end()){
t.erase(it2);
ans.push_back(now);
ans.push_back(sum-now);
sum=max(now,sum-now);
}
else return 0;
}
return 1;
}
#define read read()
int main() {
ll t;
cin>>t;
while(t--) {
cin>>n;
n=n*2;
s.clear();
for(int i = 1;i<=n;i++){
cin>>a[i];
s.insert(a[i]);
}
sort(a+1,a+1+n);
bool flag=0;
for(int i=n-1;i>=1;i--){
if( check1(a[i]+a[n]) ){
flag=1;
break;
}
}
if(flag){
printf("YES\n");
printf("%lld\n",ans[0]+ans[1]);
ll size1=ans.size();
for(int i=0;i<size1;i+=2){
printf("%lld %lld\n",ans[i],ans[i+1]);
}
}else puts("NO");///
}
return 0;
}