Codeforces 1474C.ArrayDestruction

トピックリンク

題名:

2n個の数値のシーケンスが与えられた場合、最初に任意のx値を選択し、シーケンス内で2つの数値を見つけて、これら2つの数値の合計がxに等しくなるようにすることができます。次に、これら2つの数値を削除し、xをこれら2つの数値の最大値に等しくします。シーケンス全体が削除されるまで。
質問:シーケンスを完全に削除できるように、xの初期値を見つけてください。完全に削除できない場合は、NOを出力してください。

アイデア:

各操作が完了すると、xは削除された2つの数値の最大値に等しくなるためです。したがって、すべての番号を削除できるようにするには、削除された番号の各ペアに、現在のシーケンスの最大値が含まれている必要があります。

したがって、現在のシーケンスで最大の値を使用する必要があるたびに、後で使用しないと使用できなくなり、削除されていない数値が存在するためです。番号は、シーケンス内で最大の番号である必要があります。他の番号は自由に選択できますが、条件が満たされているかどうかを後で判断する必要があります。

この場合、各xが実行可能かどうかを維持および判断する必要があり、(sum-maximum)が存在するかどうかをすばやく見つけることができます。継続する更新合計がある場合、存在しない場合は実行不可能です。

この場所はマルチセットを使用する必要があります。要素をすばやく見つけて削除できます。

#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