zoukankan      html  css  js  c++  java
  • Codeforces Round #508 (Div. 2) D. Slime

    D. Slime

    题目链接:https://codeforces.com/contest/1038/problem/D

    题意:

    给出两个数,然后每次可以对相邻的两个数合并,比如x,y,那么合并过后就是x-y或者y-x,这里怎么去减是自己决定的。问怎么合并,最后得到的那个数最大。

    题解:

    这题主要关键就是发现,最后的式子呈现出来的状态,+、-这两个符号一定是两者都有的,至少存在一个(只有一个数时除外),并且状态覆盖了+、-所有的排列。

    发现这个性质过后,贪心解一下就行了。我的做法就是模拟的方法,首先将所有正数取完,然后减去所有负数,当然注意对一些边界条件的判断。

    但还有更为机智的做法,就是首先将所有数的绝对值加在一起,然后根据式子中最大值、最小值来确定答案。

    如果最大值小于0,就应该把答案减去最大值的两倍;如果最小值大于0,就应该把答案加上最小值的两倍;另外的情况不用管了。

    我给出我的代码吧:

    #include <bits/stdc++.h>
    #define mp make_pair
    using namespace std;
    typedef long long ll;
    const int N = 500005;
    int n;
    ll a[N];
    priority_queue <pair<ll,int> > q;
    int main(){
        ios::sync_with_stdio(false);cin.tie(0);
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            q.push(mp(a[i],i));
        }
        if(n==1){
            cout<<a[1];
            return 0;
        }
        int cnt = 0;
        ll ans = 0;
        while(!q.empty()){
            pair<ll,int> now=q.top();
            //cout<<now.first<<" "<<now.second<<endl;
            if(now.first>=0){ 
                cnt++;q.pop();
                if(q.empty()) ans-=now.first;
                else ans+=now.first;
            }else{
                if(cnt==0) ans+=now.first,q.pop();
                break ;
            }
        }
        while(!q.empty()){
            pair<ll,int> now=q.top();q.pop();
            ans-=now.first;
        }
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    Qt之xml文件解析
    Qt之connect
    Qt线程池
    电力电子PSIM仿真——PWM控制
    电力电子Simulink仿真——PWM控制
    电力电子Simulink仿真——直流直流
    电力电子Simulink仿真——整流电路
    电力电子Simulink仿真——电力电子器件
    信号与系统MATLAB仿真——LTI连续系统的时域分析
    信号与系统MATLAB仿真——信号及其运算
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10507293.html
Copyright © 2011-2022 走看看