CodeForces - 721D 贪心+优先队列(整理一下优先队列排序情况)
题意:
给你一个长度为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 贪心+优先队列(整理一下优先队列排序情况)的更多相关文章
- 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) ...
- Codeforces 721D [贪心]
/* 不要低头,不要放弃,不要气馁,不要慌张. 题意: 给一列数a,可以进行k次操作,每次操作可以选取任意一个数加x或者减x,x是固定的数.求如何才能使得这个数列所有数乘积最小. 思路: 贪心...讨 ...
- Maxim and Array CodeForces - 721D (贪心)
大意: 给定序列, 每次操作选择一个数+x或-x, 最多k次操作, 求操作后所有元素积的最小值 贪心先选出绝对值最小的调整为负数, 再不断选出绝对值最小的增大它的绝对值 #include <io ...
- C - Ordering Pizza CodeForces - 867C 贪心 经典
C - Ordering Pizza CodeForces - 867C C - Ordering Pizza 这个是最难的,一个贪心,很经典,但是我不会,早训结束看了题解才知道怎么贪心的. 这个是先 ...
- POJ - 3190 Stall Reservations 贪心+自定义优先级的优先队列(求含不重叠子序列的多个序列最小值问题)
Stall Reservations Oh those picky N (1 <= N <= 50,000) cows! They are so picky that each one w ...
- Codeforces 677D - Vanya and Treasure - [DP+优先队列BFS]
题目链接:http://codeforces.com/problemset/problem/677/D 题意: 有 $n \times m$ 的网格,每个网格上有一个棋子,棋子种类为 $t[i][j] ...
- [luoguP2672] 推销员(贪心 + 树状数组 + 优先队列)
传送门 贪心...蒟蒻证明不会... 每一次找最大的即可,找出一次最大的,数列会分为左右两边,左边用stl优先队列维护,右边用树状数组维护.. (线段树超时了....) 代码 #include < ...
- codeforces 1283F. DIY Garland(树+优先队列)
题目连接:https://codeforces.com/contest/1283/problem/F 题意:一根电线连接着两个点,这两个点分别代表着两个灯,灯有自己的编号i,其亮度是2 ^ i,每根电 ...
- Codeforces Beta Round #94 div2 D 优先队列
B. String time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...
随机推荐
- Ubuntu 18.04.4 LTS 更换国内系统源
Ubuntu 18.04.4 LTS 更换国内系统源 1.1) 好习惯先做备份在干活: mv /etc/apt/sources.list /etc/apt/sources.list.bak 1.2) ...
- rm: cannot remove `/tmp/localhost-mysql_cacti_stats.txt': Operation not permitted
[root@DBslave tmp]# chown zabbix.zabbix /tmp/localhost-mysql_cacti_stats.txt
- C语言中左值和右值的区别(C语言学习笔记)
重要的内容要重复强调: C语言的术语Ivalue指用于识别或定位一个存储位置的标识符.( 注意:左值同时还必须是可改变的) 其实rvalue的发明完全是为了搭配lvalue , rvalue你可以理解 ...
- Python数据模型与Python对象模型
数据模型==对象模型 Python官方文档说法是"Python数据模型",大多数Python书籍作者说法是"Python对象模型",它们是一个意思,表示&quo ...
- 一步步使用SpringBoot结合Vue实现登录和用户管理功能
前后端分离开发是当今开发的主流.本篇文章从零开始,一步步使用SpringBoot结合Vue来实现日常开发中最常见的登录功能,以及登录之后对用户的管理功能.通过这个例子,可以快速入门SpringBoot ...
- iDRAC RAC0218 最大会话数
戴尔服务器IDRAC能ping通,但是网页打不开的时候: 用putty登录: /admin1-> racadm racreset RAC reset operation initated suc ...
- LiteOS调测利器:backtrace函数原理知多少
摘要:本文将会和读者分享LiteOS 5.0版本中Cortex-M架构的backtrace软件原理及实现,供大家参考和学习交流. 原理介绍 汇编指令的执行流程 图 1 汇编指令的执行顺序 上图1所示, ...
- XA Transactions
XA Transactions XA is a two-phase commit protocol that is natively supported by many databases and t ...
- virtualenv安装和配置
安装命令 命令执行结束 配 执行命令:virtualenv testvir 执行完成:会在当前目录下生成如下文件夹 进入到testvir目录 进入Scripts目录: 进入虚拟环境:执行 activa ...
- 三:SpringBoot-配置系统全局异常映射处理
三:SpringBoot-配置系统全局异常映射处理 1.异常分类 1.1 业务异常 1.2 系统异常 2.自定义异常处理 2.1 自定义业务异常类 2.2 自定义异常描述对象 2.3 统一异常处理格式 ...