传送门
题目描述
给你一组数,首先确定一个x,然后在这组数上找出两个数ai和aj,加和等于x,消去,然后用两个数的较大值代替x,继续下一轮,问能否将这组数字全部删除
分析
首先第一轮我们肯定要去选择一个最大的,然后我们去枚举另一个数选什么,然后再继续下一轮就可以了
代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
#include <cstring>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 10;
int a[N];
bool st[N];
PII ans[N];
int n;
bool cmp(int x,int y){
return x > y;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
map<int,int> M;
scanf("%d",&n);
for(int i = 1;i <= n * 2;i++) {
scanf("%d",&a[i]);
}
sort(a + 1,a + 1 + n * 2);
int res = 0;
int ppp;
for(int i = 1;i < 2 * n;i++){
for(int j = 1;j <= 2 * n;j++) st[j] = false;
res = 0;
int maxv = a[n * 2];
ans[++res] = {
a[i],a[2 * n]};
st[2 * n] = true;
st[i] = true;
ppp = a[i] + a[2 * n];
for(int j = 2 * n - 1;j;j--){
if(st[j]) continue;
int p = lower_bound(a + 1,a + 1 + 2 * n,maxv - a[j]) - a;
while(st[p] && p < 2 * n) p++;
// cout << maxv << ' ' << a[j] << ' ' << p << ' '<< a[p] << endl;
if(a[p] == maxv - a[j] && !st[p] && j != p){
st[j] = true;
st[p] = true;
ans[++res] = {
max(a[j],maxv - a[j]),min(a[j],maxv - a[j])};
maxv = max(a[j],maxv - a[j]);
}
}
// cout << res << endl;
if(res == n) break;
}
if(res == n) {
puts("YES");
printf("%d\n",ppp);
for(int i = 1;i <= n;i++) printf("%d %d\n",ans[i].first,ans[i].second);
}
else puts("NO");
}
return 0;
}
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/