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; }
(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; }
时间: 2024-10-29 19:05:40