CF #374 (Div. 2) D. 贪心,优先队列或set

Posted 掉血菜鸡煮熟中

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF #374 (Div. 2) D. 贪心,优先队列或set相关的知识,希望对你有一定的参考价值。

1、CF #374 (Div. 2)   D. Maxim and Array    

2、总结:按绝对值最小贪心下去即可

3、题意:对n个数进行+x或-x的k次操作,要使操作之后的n个数乘积最小。

(1)优先队列

#include<bits/stdc++.h>
#define F(i,a,b) for (int i=a;i<b;i++)
#define FF(i,a,b) for (int i=a;i<=b;i++)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N=200100,MAX=1000100;

struct Num
{
    int i;
    LL val;     //一开始用int,一直挖9
    bool operator <(const Num &a1)const {
        return abs(val)>abs(a1.val);
    }
}a[N];

int main()
{
    int n,k,num1;
    LL x;
    while(~scanf("%d%d%lld",&n,&k,&x))
    {
        priority_queue<Num>Q;
        num1=0;
        F(i,0,n){
            scanf("%lld",&a[i].val);
            a[i].i=i;
            Q.push(a[i]);
            if(a[i].val<0)num1++;
        }
        Num ans;
        while(k--){
            ans=Q.top();Q.pop();
            if(num1%2) {
                if(ans.val==0){
                    ans.val+=x;
                }else if(ans.val>0){
                    ans.val+=x;
                }else {
                    ans.val-=x;
                }
            }else {
                if(ans.val==0){
                    ans.val-=x;
                    if(ans.val<0)num1++;
                }else if(ans.val>0){
                    ans.val-=x;
                    if(ans.val<0)num1++;
                }else {
                    ans.val+=x;
                    if(ans.val>=0)num1--;
                }

            }
            a[ans.i]=ans;
            Q.push(ans);
        }
        printf("%lld",a[0].val);
        F(i,1,n)printf(" %lld",a[i].val);
        puts("");

    }

    return 0;
}
View Code

(2)set

#include<bits/stdc++.h>
#define F(i,a,b) for (int i=a;i<b;i++)
#define FF(i,a,b) for (int i=a;i<=b;i++)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N=200010,MAX=1000100;

int main()
{
    int n,k,flag;
    LL x,a[N];
    while(~scanf("%d%d%lld",&n,&k,&x))
    {
        flag=0;
        set<pair<LL,int> >S;
        F(i,0,n){
            scanf("%lld",&a[i]);
            if(a[i]<0)flag^=1;
            S.insert(make_pair(abs(a[i]),i));

        }
        while(k--){
            int pos=S.begin()->second;S.erase(S.begin());
            if(flag){
                if(a[pos]>=0)a[pos]+=x;
                else a[pos]-=x;
            }else {
                if(a[pos]>=0){
                    a[pos]-=x;
                    if(a[pos]<0)flag^=1;
                }
                else {
                    a[pos]+=x;
                    if(a[pos]>=0)flag^=1;
                }
            }
            S.insert(make_pair(abs(a[pos]),pos));
        }
        cout<<a[0];
        F(i,1,n)printf(" %lld",a[i]);
        cout<<endl;

    }

    return 0;
}
View Code

 

以上是关于CF #374 (Div. 2) D. 贪心,优先队列或set的主要内容,如果未能解决你的问题,请参考以下文章

CF #374 (Div. 2) C. Journey dp

CF #375 (Div. 2) D. bfs

CF-Div2-832 D. Yet Another Problem(bitmask&结论)

CF-Div2-832 D. Yet Another Problem(bitmask&结论)

CF 666 (Div. 2) D. Stoned Game博弈论

CF 666 (Div. 2) D. Stoned Game博弈论