首页 > 代码库 > Codeforces 721D [贪心]

Codeforces 721D [贪心]

/*不要低头,不要放弃,不要气馁,不要慌张。题意:给一列数a,可以进行k次操作,每次操作可以选取任意一个数加x或者减x,x是固定的数。求如何才能使得这个数列所有数乘积最小。思路:贪心...讨论这列数中负数的个数,如果为偶数,那么把数列中绝对值最小的数使其往0的方向前进。如果为奇数,同样选择绝对值最小的数,使其往背离0的方向前进。道理很简单...自己写写就看出来了...wa点:有一个细节没处理好,如果经过某次操作某个数变成0了...那么我们的负数记录并没有更新...默认下一次会减...因为我们需要构造一个新的负数...所以这里gg了...*/#include<bits/stdc++.h>#define N 200050using namespace std;long long jilu[N];long long ans[N];struct st{    st(){}    st(long long a,int aa){        bb=a;        jue=max(a,-a);        id=aa;    }    int id;    long long bb,jue;};bool operator < (const st &a,const st &b){    return a.jue<b.jue;}multiset<st> ms;int main(){    int n,k;    long long x;    int zero=0,zheng=0,fu=0;    scanf("%d%d%lld",&n,&k,&x);    int ddd=0;    for(int i=1;i<=n;i++){        scanf("%lld",jilu+i);        if(jilu[i]!=-1000000000)ddd++;        if(jilu[i]==0)zero++;        else if(jilu[i]>0)zheng++;        else fu++;    }    for(int i=1;i<=n;i++)ms.insert(st(jilu[i],i));    st tmp;    for(int i=1;i<=k;i++){        tmp=*ms.begin();        ms.erase(ms.begin());        if(fu%2==0){            if(tmp.jue<=x)fu++;            if(tmp.bb>=0){                tmp.bb-=x;                if(tmp.bb==0&&i!=k){                    i++;                    tmp.bb-=x;                }            }            else{                tmp.bb+=x;                if(tmp.bb==0&&i!=k){                    tmp.bb+=x;                    i++;                }            }            ms.insert(st(tmp.bb,tmp.id));        }        else{            if(tmp.bb>=0)tmp.bb+=x;            else tmp.bb-=x;            ms.insert(st(tmp.bb,tmp.id));        }    }    multiset<st>::iterator it;    for(it=ms.begin();it!=ms.end();it++){        ans[it->id]=it->bb;    }    for(int i=1;i<=n;i++){        printf("%lld ",ans[i]);    }}

 

Codeforces 721D [贪心]