题意:

给你一个长度为n的数组,你可以对其中某个元素加上x或者减去x,这种操作你最多只能使用k次,让你输出操作后的数组,且保证这个数组所有元素的乘积尽可能小

题解:

在这之前我们要知道a*b>a*(b-x)>(a-x)*b    在a-x>0且b-x>0情况下

首先要讨论这n个元素中负数个数有多少个

1、如果负数有奇数个,那么就让绝对值靠近0的数往距离0远点(也就是负数-x,正数+x),这样操作k次后,等到的数组就满足题意

2、如果没有负数,那么首先判断可不可以让一个正数变成负数

2.1、如果可以那么找一个最小的正数变成负数之后(假设这个过程用了y次操作),然后就转化成了问题1,剩下k-y次操作让绝对值靠近0的数往距离0远点

2.2、如果不可以,那就让那个最小的正数尽可能变小

3、负数个数为偶数个,找一个绝对值最小的数,如果这个数是正数,那就把它变成负数(这个时候要看可不可以变成负数,相似于2.1,2.2);如果这个数是负数,那就把它变成正数(这个时候要看可不可以变成正数,相似于2.1,2.2)

代码:

  1 #include <iostream>
2 #include <cstdio>
3 #include <cstdlib>
4 #include <math.h>
5 #include <string.h>
6 #include <queue>
7 #include <set>
8 #include <map>
9 #include <algorithm>
10 using namespace std;
11 const int maxn=2e5+10;
12 const int inf=0x3f3f3f3f;
13 const int MAXN = 2e5+10;
14 typedef long long LL;
15 struct Node
16 {
17 int pos;
18 LL val;
19 bool operator < (const Node& that) const
20 {
21 return abs(this->val) > abs(that.val);
22 }
23 }node[MAXN];
24 int n;
25 LL k, x;
26
27 void Solve()
28 {
29 priority_queue<Node> que;
30 for (int i = 1;i <= n;i++)
31 que.push(node[i]);
32 while (k)
33 {
34 Node now = que.top();
35 que.pop();
36 if (now.val >= 0)
37 now.val += x;
38 else
39 now.val -= x;
40 que.push(now);
41 k--;
42 }
43 while (!que.empty())
44 {
45 node[que.top().pos] = que.top();
46 que.pop();
47 }
48 for (int i = 1;i <= n;i++)
49 printf("%lld ", node[i].val);
50 printf("\n");
51 }
52
53 int main()
54 {
55 scanf("%d %d %lld", &n, &k, &x);
56 int cnt = 0;
57 for (int i = 1;i <= n;i++)
58 {
59 scanf("%lld", &node[i].val);
60 node[i].pos = i;
61 if (node[i].val < 0)
62 cnt++;
63 }
64 if (cnt == 0)
65 {
66 int mpos = 1;
67 for (int i = 1;i <= n;i++)
68 {
69 if (node[i].val < node[mpos].val)
70 mpos = i;
71 }
72 LL ti = (node[mpos].val+1LL+x-1)/x;
73 if (ti > k)
74 node[mpos].val -= k*x;
75 else
76 node[mpos].val -= ti*x;
77 k -= min(ti, k);
78 }
79 else if (cnt > 0 && cnt%2 == 0)
80 {
81 int mpos = 1;
82 for (int i = 1;i <= n;i++)
83 {
84 if (abs(node[i].val) < abs(node[mpos].val))
85 mpos = i;
86 }
87 if (node[mpos].val >= 0)
88 {
89 LL ti = (node[mpos].val+1LL+x-1)/x;
90 if (ti > k)
91 node[mpos].val -= k*x;
92 else
93 node[mpos].val -= ti*x;
94 k -= min(ti, k);
95 }
96 else
97 {
98 LL ti = (abs(node[mpos].val)+1LL+x-1)/x;
99 if (ti > k)
100 node[mpos].val += k*x;
101 else
102 node[mpos].val += ti*x;
103 k -= min(ti, k);
104 }
105 }
106 Solve();
107
108 return 0;
109 }

优先队列排序情况:

 1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long LL;
4 const int MAXN = 2e5+10;
5 struct Node
6 {
7 int pos;
8 LL val;
9 bool operator < (const Node& that) const
10 {
11 return abs(this->val) > abs(that.val); //这个时候优先队列从小到大排序
12 //return abs(this->val) < abs(that.val); //这个时候优先队列从大到小排序
13 //return abs(that.val) > abs(this->val); //这个时候优先队列从大到小排序
14 //return abs(that.val) < abs(this->val); //这个时候优先队列从小到大排序
15 }
16 }node[MAXN],str1;
17 int main()
18 {
19 priority_queue<Node>r;
20 str1.val=1;
21 r.push(str1);
22 str1.val=2;
23 r.push(str1);
24 str1.val=3;
25 r.push(str1);
26 while(!r.empty())
27 printf("%d ",r.top().val),r.pop();
28 return 0;
29 }

CodeForces - 721D 贪心+优先队列(整理一下优先队列排序情况)的更多相关文章

  1. Codeforces 898 贪心关闭最少闹钟 优先队列最少操作构造N/2squares 讨论情况哈希数字串分割a+b=c

    A /* Huyyt */ #include <bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define mkp(a,b) ...

  2. Codeforces 721D [贪心]

    /* 不要低头,不要放弃,不要气馁,不要慌张. 题意: 给一列数a,可以进行k次操作,每次操作可以选取任意一个数加x或者减x,x是固定的数.求如何才能使得这个数列所有数乘积最小. 思路: 贪心...讨 ...

  3. Maxim and Array CodeForces - 721D (贪心)

    大意: 给定序列, 每次操作选择一个数+x或-x, 最多k次操作, 求操作后所有元素积的最小值 贪心先选出绝对值最小的调整为负数, 再不断选出绝对值最小的增大它的绝对值 #include <io ...

  4. C - Ordering Pizza CodeForces - 867C 贪心 经典

    C - Ordering Pizza CodeForces - 867C C - Ordering Pizza 这个是最难的,一个贪心,很经典,但是我不会,早训结束看了题解才知道怎么贪心的. 这个是先 ...

  5. POJ - 3190 Stall Reservations 贪心+自定义优先级的优先队列(求含不重叠子序列的多个序列最小值问题)

    Stall Reservations Oh those picky N (1 <= N <= 50,000) cows! They are so picky that each one w ...

  6. Codeforces 677D - Vanya and Treasure - [DP+优先队列BFS]

    题目链接:http://codeforces.com/problemset/problem/677/D 题意: 有 $n \times m$ 的网格,每个网格上有一个棋子,棋子种类为 $t[i][j] ...

  7. [luoguP2672] 推销员(贪心 + 树状数组 + 优先队列)

    传送门 贪心...蒟蒻证明不会... 每一次找最大的即可,找出一次最大的,数列会分为左右两边,左边用stl优先队列维护,右边用树状数组维护.. (线段树超时了....) 代码 #include < ...

  8. codeforces 1283F. DIY Garland(树+优先队列)

    题目连接:https://codeforces.com/contest/1283/problem/F 题意:一根电线连接着两个点,这两个点分别代表着两个灯,灯有自己的编号i,其亮度是2 ^ i,每根电 ...

  9. Codeforces Beta Round #94 div2 D 优先队列

    B. String time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

随机推荐

  1. xtrabackup 备份与恢复

    书上摘抄 ---深入浅出mysql 448页  grant reload on *.* to 'backup'@'localhost' identified by '123456'; grant re ...

  2. [CPP] 智能指针

    介绍 C++ 的智能指针 (Smart Pointers) 相关 API. C++ 中的智能指针是为了解决内存泄漏.重复释放等问题而提出的,它基于 RAII (Resource Acquisition ...

  3. P1967 货车运输(倍增LCA,生成树)

    题目链接: https://www.luogu.org/problemnew/show/P1967 题目描述 A国有n座城市,编号从 1到n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制, ...

  4. 注解 @AutoConfigureBefore 和 @AutoConfigureAfter 的用途

    注解 @AutoConfigureBefore 和 @AutoConfigureAfter 的用途 介绍: 如果你想将在SpringBoot项目中的配置类进行排序,那么用到spring-boot-au ...

  5. Java 迭代器的使用 Iterator

    Java的集合类可以使用for ... each循环 List Set Queue Deque 我们以List为例 其实一个java编译器并不知道如何遍历一个List 编译器只是把一个for ... ...

  6. 微信小程序 发送模板消息的功能实现

    背景 - 小程序开发的过程中,绝大多数会满足微信支付 - 那么,作为友好交互的体现,自然就会考虑到支付后的消息通知咯 - 所以,我的小程序项目也要求完成这个效果,so.分享一下自己的实现步骤,以方便道 ...

  7. 【Android初级】使用TypeFace设置TextView的文字字体(附源码)

    在Android里面设置一个TextView的文字颜色和文字大小,都很简单,也是一个常用的基本功能.但很少有设置文字字体的,今天要分享的是通过TypeFace去设置TextView的文字字体,布局里面 ...

  8. 最佳的思维导图生成工具——markmap 使用教程

    前言 相信很多程序员朋友都有在用 Markdown 吧,我是大三找实习工作的时候接触到的,简历就是用 Markdown 写的. Markdown 的好处是专注码字的同时还能兼顾排版,不用像 word ...

  9. DDOS攻击方式总结以及免费DDOS攻击测试工具大合集

    若有雷同或者不足之处,欢迎指正交流,谢谢! DoS(Denial Of Service)攻击是指故意的攻击网络协议实现的缺陷或直接通过野蛮手段残忍地耗尽被攻击对象的资源,目的是让目标计算机或网络无法提 ...

  10. JAVA高并发集合详解

    Queue(队列)主要是为了高并发准备的容器Deque:双端队列,可以反方向装或者取 最开始jdk1.0只有Vector和hashtable 默认所有方法都实现了synchronized锁,线程安全但 ...