题目链接
题意:
给出一个2n个数的序列,一开始你可以任选一个x值,然后在序列中找到两个数,使得这两个数的和等于x。然后删除这两个数,并让x等于这两个数中的最大值。直到整个序列全部被删除为止。
问:求一个初始的x值,使序列能被完全删除。如果不能被完全删除,输出NO。
思路:
因为每次操作进行完后,x都会等于删除的两个数中的最大值。因此为了能够将所有数删除,每次删除的一对数中必然包含着当前序列中的最大值。
所以每次我们都需要用到当前序列中最大的数值,因为如果你不用后面将无法再用到这样,就存在没有消掉的数.这样我们每一次取的数一定有序列中的最大数,另一个数可以随便选但是需要判断后面是否满足条件.
这样的话我们就需要维护并且判断每次的x是否可行,并且能够快速找到(sum-最大值)是否存在. 存在更新sum继续,不存在就不可行.
这个地方需要用到multiset.可以快速找到,删除元素.
#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;
}