codeforces1474C
https://codeforces.com/problemset/problem/1474/C
题意:
有一个数字x和一个长度为2*n的数组,每次找到两个数字a,b,使得x=a+b,并且删除掉a和b,同时x更新为max(a,b),试问能不能把这个数组全部清除,
思路:
首先排序,每次删除的肯定是这些数中最大的一个a,和x-a,假如删除了较小的a,那么比a大的数字将永远不会被删除,第一次删除的肯定是a[n]和任意一个数(不一定是第一个数字),然后模拟这个过程,每次选择最大的数字,然后删除集合中的指定数字,可以使用set完成,由于有重复,可以使用multiset配合二分函数实现
题解:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#include <vector>
#define eb emplace_back
#define divUp(a,b) (a+b-1)/b
#define mkp(x,y) make_pair(x,y)
#define all(v) begin(v),end(v)
#define int long long
using namespace std;
typedef unsigned long long ull;
typedef pair<int, int> pii;
bool checkP2(int n) { return n > 0 and (n & (n - 1)) == 0;};
const int N = 2010;
int a[N];
void solve() {
int n;
cin >> n;
n *= 2;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + 1 + n);
multiset<int, greater<int>>s;
vector<pii> v;
bool ok = true;
for (int i = 1; i <= n - 1; i++) {
s.clear();
v.clear();
ok = true;
int x = a[n];
for (int j = 1; j <= n - 1; j++) {
if (j == i) continue;
else s.insert(a[j]);
}
while (s.size()) {
auto cur = s.begin();
int cur_v = *cur;
s.erase(cur);
auto it = s.find(x - cur_v);
if (it == s.end()) {
ok = false;
}
if (!ok) break;
x = max(*it, cur_v);
v.eb(mkp(*it, cur_v));
s.erase(it);
}
if (ok) {
cout << "Yes" << endl;
cout << a[n] + a[i] << endl;
cout << a[n] << ' ' << a[i] << endl;
for (auto [x, y] : v) {
cout << x << ' ' << y << endl;
}
return ;
}
}
cout << "No" << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
int _; cin >> _; while (_--)
solve();
return 0;
}

浙公网安备 33010602011771号