码迷,mamicode.com
首页 > 其他好文 > 详细

Array Destruction

时间:2021-01-25 11:17:31      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:mes   这一   font   cout   code   stream   include   out   --   

题意

  给出一个长为2n的序列,你需要设定一个数x,每一次你可以选择序列中的两个数a和b,满足a+b等于x,然后将ab从序列中去除,最后将x变为a和b较大的那个数。如果可以把序列全部消空,输出yes和最开始的x,然后输出每一步选择的两个数。否则输出no。

思路

  我们可以知道的是每一步的两个数里面一定有当前序列中的最大值,因为这一步消除不了它,那么在接下来的步骤中都消除不了了(下一步的x比它小)。

  那么在最开始的阶段,已经确定有一个数是最大值,那么另一个数就是其余2n-1种情况

  所以我们其余2n-1个每个都试试就行,这里使用multset会非常舒服

AC代码

#include<iostream>
#include<set>
#include<vector>
#include<algorithm>
using namespace std;
int t,n;

vector<int> check(int n,vector<int> a,int x){
    multiset<int> s;
    for(auto e : a)
        s.insert(e);
    vector<int> res;
    
    for(int i=0;i<n;i++){
        auto r = s.end();
        r--;
        int y = x - *r;
        s.erase(r);
        auto l = s.find(y);
        if(l == s.end()) return {};
        res.push_back(y);
        res.push_back(x-y);
        x = max(x-y,y);
        s.erase(l);
    }
    return res;
}

int main(){
    cin>>t;
    while(t--){
        cin>>n;
        vector<int> a(2*n);
        for(int i=0;i<2*n;i++)
            cin>>a[i];
        sort(a.begin(),a.end());
        
        int flag=0;
        for(int i=0;i<2*n-1;i++){
            int x=a[i]+a[2*n-1];
            vector<int> res = check(n,a,x);
            if(res.size()){
                cout<<"YES\n";
                cout<<x<<\n;
                for(int j=0;j<n;j++){
                    cout<<res[2*j]<<" "<<res[2*j+1]<<\n;
                }
                flag=1;
                break;
            }
        }
        if(flag==0) cout<<"NO\n";
    }
    return 0;
} 

 

Array Destruction

标签:mes   这一   font   cout   code   stream   include   out   --   

原文地址:https://www.cnblogs.com/qq2210446939/p/14317227.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!