码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #374 (Div. 2)-D Maxim and Array

时间:2017-11-22 14:18:05      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:put   gif   ==   span   max   奇数   its   def   c++   

题目大意:给你n个数,最多有k次操作,每次操作可以将一个任意一个数加上x或者减去x,问你经过k次操作

之后,满足n个数乘积最小的改变后的序列。

 

思路:我们先考虑原序列由奇数个负数,那么我们只要将n个数的绝对值全部加入优先队列,然后每次操作取出

最小值,如果是负数能减去x,如果是正数加上x,这样进行将会得到最优解。

  再考虑没有负数是偶数个的情况,那么我们如果n个数中的绝对值的最小值小于x*k,则我们将这个绝对值

最小的数变成反号,然后就变成了第一种情况。 如果n个数中的绝对值的最小值大于等于x*k,如果这个数是正

数则减去x*k,负数则加上x*k。

 

有0的情况需要特殊处理一下,细节比较多,不太好写。

技术分享图片
 1 #include<bits/stdc++.h>
 2 #define pii pair<long long,int>
 3 #define mk make_pair
 4 #define fi first
 5 #define se second
 6 #define ll long long
 7 using namespace std;
 8 const int N=2*1e5+5;
 9 int n;
10 long long a[N],k,x,cnt1=0,cnt2=0;
11 pii mn,_mn;
12 priority_queue<pii,vector<pii>,greater<pii> > Q;
13 int main()
14 {
15     mn.fi=1e9+10,_mn.fi=1e9+10;
16     mn.se=0,_mn.se=0;
17     scanf("%d%lld%lld",&n,&k,&x);
18     for(int i=1;i<=n;i++)
19     {
20         scanf("%lld",&a[i]);
21         if(a[i]<0)
22         {
23             cnt1++;
24             _mn=min(_mn,mk(-a[i],i));
25         }
26         else if(a[i]>0) mn=min(mn,mk(a[i],i));
27         else cnt2++;
28     }
29     if(cnt2>k)
30     {
31         for(int i=1;i<=n;i++) printf("%lld ",a[i]);
32         return 0;
33     }
34     if(cnt2)
35     {
36         bool flag=false;
37         for(int i=1;i<=n;i++)
38         {
39             if(a[i]!=0) continue;
40             if(!(cnt1&1))
41             {
42                 a[i]-=x;
43                 cnt1++;
44             }
45             else a[i]+=x;
46             k--;
47         }
48     }
49     if(!(cnt1&1))
50     {
51         ll w=k*x;
52         if(mn.fi<=_mn.fi)
53         {
54             if(mn.fi<w)
55             {
56                 cnt1++;
57                 int u=(mn.fi+1)/x;
58                 if((mn.fi+1)%x!=0) u++;
59                 k-=u;
60                 a[mn.se]-=u*x;
61             }
62             else a[mn.se]-=w,k=0;
63         }
64         else
65         {
66             if(_mn.fi<w)
67             {
68                 cnt1--;
69                 int u=(_mn.fi+1)/x;
70                 if((_mn.fi+1)%x!=0) u++;
71                 k-=u;
72                 a[_mn.se]+=u*x;
73             }
74             else a[_mn.se]+=w,k=0;
75         }
76     }
77     if(cnt1&1)
78     {
79         for(int i=1;i<=n;i++)
80         {
81             if(a[i]==0)
82             {
83                 a[i]+=x;
84                 k--;
85             }
86             Q.push(mk(abs(a[i]),i));
87         }
88         while(k--)
89         {
90             pii cur=Q.top(); Q.pop();
91             if(a[cur.se]<0) a[cur.se]-=x;
92             else a[cur.se]+=x;
93             Q.push(mk(abs(a[cur.se]),cur.se));
94         }
95     }
96     for(int i=1;i<=n;i++) printf("%lld ",a[i]);
97     puts("");
98     return 0;
99 }
View Code

 

Codeforces Round #374 (Div. 2)-D Maxim and Array

标签:put   gif   ==   span   max   奇数   its   def   c++   

原文地址:http://www.cnblogs.com/CJLHY/p/7878650.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!