Codeforces Round 374 (Div 2)D Maxim and Array 【贪心】

来源:互联网 发布:淘宝买快排会查下来吗 编辑:程序博客网 时间:2024/05/21 14:20
【题意】
n个数,我们可以做k次操作,每次选定一个数,+x或-x,在这种条件下,让你求出怎么操作,可以使得乘积最小

【分析】
显然,如果负数个数为奇数,我们只需要使得所有数符号不变的条件下,绝对值尽可能大(从绝对值较小者开始递增)

如果负数个数为偶数,我们要先使得一个绝对值最小的数变号(非负->负 或 负->非负),然后再做上面的操作

#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<ctype.h>#include<math.h>#include<set>#include<map>#include<vector>#include<queue>#include<bitset>#include<algorithm>#include<time.h>using namespace std;void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }#define MS(x,y) memset(x,y,sizeof(x))#define ls o<<1#define rs o<<1|1typedef long long LL;typedef unsigned long long UL;typedef unsigned int UI;template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }const int N = 2e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }int casenum, casei;int n, K, X;LL a[N];struct node{LL x;int sg;int p;bool operator < (const node &b)const{if (abs(x) != abs(b.x))return abs(x) < abs(b.x);//使得绝对值小的排在前面return p < b.p;}};set< node >sot;int main(){while(~scanf("%d%d%d",&n,&K,&X)){sot.clear();int neg = 0;for (int i = 1; i <= n; ++i){int x; scanf("%d", &x);int sg = (x >= 0 ? 1 : -1);if (x < 0)++neg;sot.insert({ x, sg, i });}if (neg % 2 == 0)//负数个数为偶数,这种情况下,我们要变号{while (K){--K;LL x = sot.begin()->x;int sg = sot.begin()->sg;int p = sot.begin()->p;sot.erase(sot.begin());if ((x - X * sg) * sg <= 0){sot.insert({ x - X * sg, -sg, p });break;}else{sot.insert({ x - X * sg, sg, p });}}}while (K){--K;LL x = sot.begin()->x;int sg = sot.begin()->sg;int p = sot.begin()->p;sot.erase(sot.begin());sot.insert({ x + X * sg, sg, p });}for (auto it : sot)a[it.p] = it.x;for (int i = 1; i <= n; ++i)printf("%lld ", a[i]);puts("");}return 0;}


0 0
原创粉丝点击