题意:给出n个数,k次机会,每次机会可以使得任意一个数字减少或者加上x,问使得最后的乘积最小的n个数,每个数是多少。

  分析:贪心思路是每次取出绝对值最小的一个数,判断乘积的符号以及这个数的符号来做出加或者减的操作。

  具体见代码:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <iostream>
 5 #include <queue>
 6 #include <math.h>
 7 using namespace std;
 8 
 9 const int N = 200000 + 50;
10 typedef long long ll;
11 
12 ll aabs(ll x) {return x<0 ? -x : x;}
13 
14 struct node
15 {
16     ll num;
17     int id;
18     bool operator < (const node & temp) const
19     {
20         return aabs(num) > aabs(temp.num);
21     }
22 };
23 
24 ll a[N];
25 ll n,k,x;
26 
27 int main()
28 {
29     cin >> n >> k >> x;
30     int sign = 1;
31     priority_queue<node> Q;
32     for(int i=1;i<=n;i++)
33     {
34         scanf("%I64d",a+i);
35         if(a[i] < 0) sign = -sign;
36         Q.push((node){a[i],i});
37     }
38     while(k--)
39     {
40         node temp = Q.top();Q.pop();
41         if(a[temp.id] < 0)
42         {
43             if(sign == -1) a[temp.id] -= x;
44             else a[temp.id] += x;
45             if(a[temp.id] >= 0) sign = -sign;
46         }
47         else
48         {
49             if(sign == -1) a[temp.id] += x;
50             else a[temp.id] -= x;
51             if(a[temp.id] < 0) sign = -sign;
52         }
53         Q.push((node){a[temp.id],temp.id});
54     }
55     for(int i=1;i<=n;i++)
56     {
57         printf("%I64d%c",a[i],i==n?'\n':' ');
58     }
59 }

 

  顺便回顾一下,优先队列是默认的每次弹出优先级最大的元素(默认less),,好久没用优先队列都忘了= =。。