题意:

给你一个长度为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. spring boot gateway 过滤器的执行顺序

    前言 学习官方文档,发现对于过滤器有分为三类 默认过滤器 自定义过滤 全局过滤器 于是就有一个疑问,关于这些过滤器的访问顺序是怎样的,今天就以一个demo来进行测试 准备阶段 过滤器工厂类 以此为模板 ...

  2. MySQL sql命令行操作数据库

    数据库命令行操作 命令行操作数据库, [if exists] 可加可不加, 命令行操作一定要加英文分号 ; 结尾 创建数据库 : create database [if not exists] 数据库 ...

  3. 【Web】CSS实现鼠标悬停实现显示与隐藏 特效

    鼠标悬停实现显示与隐藏特效 简单记录 - 慕课网 Web前端 步骤四:鼠标悬停实现显示与隐藏特效 初步掌握定位的基本使用,以及CSS选择器更高级的运用,完成一个网页中必会的鼠标经过隐藏显示特效. 实现 ...

  4. LeetCode938. 二叉搜索树的范围和

    题目 1 class Solution { 2 public: 3 int sum = 0; 4 int rangeSumBST(TreeNode* root, int low, int high) ...

  5. new String("ab")到底创建了几个对象说明

    new String("ab")到底创建了几个对象? 之前一直被这个问题困扰,网上一些描述的都不是很清楚,自己看了一些资料可算搞清楚了,那就在博客上记录一下吧! String st ...

  6. Spring Bean详解

    Spring Bean 在Spring的应用中,Spring IoC容器可以创建.装配和配置应用组件对象,这里的组件对象称为Bean. Bean的配置 Spring可以看作一个大型工厂,用于生产和管理 ...

  7. 前端知识(一)05 axios-谷粒学院

    目录 一.axios的作用 二.axios实例 1.复制js资源 2.创建 axios.html 3.引入js 4.启动课程中心微服务 5.编写js 6.html渲染数据 7.跨域 8.使用生命周期函 ...

  8. 订阅者模式,公众号、B站、快手用了都说好!

    大家好,今天和大家来聊一个新的设计模式--订阅者模式. 这个模式在我们的生活当中非常常见,可以说是几乎所有的媒体平台都用或多或少地用到了这个模式.比如公众号,我们来仔细梳理一下公众号这个平台当中的整个 ...

  9. CoeMonkey少儿编程第4章 变量

    点击这里,现在就开启CodeMonkey的趣味编程之旅. 目标 了解什么是变量 了解变量的命名规则 掌握如何使用变量 变量 什么是变量?顾名思义,变量就是可以变化的量. 和变量相对的是常量,即不可变化 ...

  10. ES6在工作中会用到的核心知识点讲解

    一.var, let, const 谈到ES6,估计大家首先肯定会想到var,let,const 咱就先谈谈这三者的区别 var a = 3; { var a = 4; } console.log(a ...