Codeforces 1474C.Array Destruction

题目链接

题意:

给出一个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;
}

猜你喜欢

转载自blog.csdn.net/weixin_45911397/article/details/114876039