1. 程式人生 > 實用技巧 >Codeforces Round #696 (Div. 2)補題

Codeforces Round #696 (Div. 2)補題

C. Array Destruction

C. Array Destruction

題意

給定長度為2n的陣列,一開始選定一個數X,將陣列中的兩個和為X的數a和b刪除,同時令X=max(a,b),重複該動作,直到陣列所有元素刪除完畢。如果能,輸出YES和步驟,不能輸出NO。

思路

分解後的兩個數一定是陣列中可利用的的最大值和其中的某一個數

反證法:假設被分解的數不是可利用的最大的數,那麼這個最大的數在之後的分解中必不能再被用到, 因為它太大了,將會大於欲分解的數

程式碼

/*************************************************************************
 > FileName:
 > Author:      Lance
 > Mail:        [email protected]
 > Date:        9102.1.8
 > Description:
 ************************************************************************/
//#include <bits/stdc++.h>
//#pragma comment(linker, "/STACK:102400000,102400000")//add_stack
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <vector>
#include <cstdio>
#include <bitset>
#include <string>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const double pi = acos(-1.0);
const double eps = 1e-6;
const int mod = 1e9 + 7;
#define debug(a) cout << "*" << a << "*" << endl
const int INF = 0x3f3f3f3f;//int2147483647//ll9e18//unsigned ll 1e19
const int maxn = 1000005;
//sacnf("%lf") printf("%f")
ll read()
{
    ll x = 0,f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
	{
		if (ch == '-')
		f = -1;
		ch = getchar();
	}
    while (ch >= '0' && ch <= '9')
	{
		x = x * 10 + ch - '0';
		ch = getchar();
	}
    return x * f;
}
int t, n, a[maxn], flag = 0;
multiset<int> S;
vector<int> ANS;
void solve()
{
	t = read();
	while (t--) {
		flag = 0;
		n = read();
		for (int i = 0; i < n * 2; i++) {
			a[i] = read();
		}
		sort(a, a + 2 * n);
		for (int i = 0; i < n * 2 - 1; i++) {
			int x = a[i] + a[2 * n - 1];
			S.clear();
			ANS.clear();
			for (int j = 0; j < 2 * n; j++) {
				S.insert(a[j]);
			}

			for (int j = 0; j < n; j++) {
				auto itend = S.end();
				itend--;
				int y = x - *itend;
				S.erase(itend);
				auto it2 = S.find(y);
				if (it2 == S.end()) {
					break;
				} else {
					ANS.push_back(x - y);
					ANS.push_back(y);
					x = max(y, x - y);
					S.erase(it2);
				}
			}
			
			
			if (ANS.size() == n * 2) {
				puts("YES");
				cout << ANS[0] + ANS[1] << endl;
				for (int i = 0; i < ANS.size(); i+=2) {
					cout << ANS[i] << ' ' << ANS[i + 1] << endl;
				}
				flag = 1;
				break;
			}
		}
		if (flag == 0) {
			puts("NO");
		}
	}
}

int main()
{

//    freopen("F:/Overflow/in.txt","r",stdin);
//    ios::sync_with_stdio(false);
    solve();
    return 0;
}

D. Cleaning

D. Cleaning

題意

思路

程式碼


小結

菜雞a兩題,B兩次罰時,因為情況沒有考慮清楚。

C題暴搜wa兩發,一開始思路是對的,卻沒動手寫。

參考

https://blog.csdn.net/qq_43857314/article/details/112855909s