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

 

转载于:https://www.cnblogs.com/sbfhy/p/5932317.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值