Codeforces Round #474-B(贪心)
一、题目链接
http://codeforces.com/contest/960/problem/B
二、题意
给定三个数字$N, k1, k2$,接下来给出两组数$a[]$和$b[]$,每组数$N$个,对$a$组数操作$k1$次,对$b$组数操作$k2$次,每次操作都可以从指定的数组中选择任意一个数加$1$或减$1$。求操作完$k1$和$k2$之后,最小的差分平方和$\sum\limits_{i=1}^{N}(a_i - b_i)^2$。
三、思路
其实思路很简单,只是当时时间比较晚了,几乎精疲力竭,导致脑子一片浆糊。
假设差分数组为$c[]$,$c_i = a_i - b_i$,每次从$c[]$中选出绝对值最大的数,那么,考虑$a_i$和$b_i$的大小关系,同时,再考虑$k1$和$k2$的大小关系。目的都是使两个数($a_i$和$b_i$)的差距尽可能小。那么,如果$k1<k2$,优先操作$a[]$,否则优先操作$b[]$。这里的逻辑在代码中非常明显,不过多解释。
关键是这一点:$a[]$和$b[]$全相等时的情况。
(1)如果$k1>0$且$k2>0$,那么这时正确的做法不是把$k1$均分到$a[]$上,把$k2$均分到$b[]$上。而是,反复对某一个数加$1$减$1$。那么,这样的话,最后的结果,最多就是$1$,否则就是$0$,这比均分更优。易知,在这种情况下,结果为$1$的条件是$k1$和$k2$奇偶相异。
(2)如果$k1$或$k2$中某一个大于$0$,做法和上面的一样。
(3)否则,必定$k1\ =\ 0$且$k2\ =\ 0$。(其实这从if-elseif-else结构也可以推出来了)。
(4)不可能出现$k1$和$k2$其中某一个大于$0$或两个都大于$0$而且$\exists_i, 1 \le i \le N, a[i] \ne b[i]$的情况。想想便知,如果存在某个差分$a_i - b_i \ne 0$,且$k1$和$k2$其中某一个大于$0$或两个都大于$0$,那为何不使他们靠的更近一些呢,这不是更好吗,是吧。
其实上面的逻辑感觉还挺麻烦的。参考了一个下rank1的代码,思路、代码都非常清晰简洁。直接记录差分数组$c_i = a_i - b_i$,计算出总的可操作次数。然后每次从$\left\|c_i\right\|$中选出一个最大的数$c_i$,如果$c_i>0$,那么,$c_i--$,否则$c_i++$。同时,总的可操作次数减$1$。当操作次数用完的时候,计算答案即可。妙!!!当数组$c[]$全为$0$时,只要总操作次数大于$0$,它肯定会选一个$c_i$减$1$,下次它肯定会被再次选出来加$1$。这样,这个$c_i$就被反复的加$1$减$1$了。非常巧妙!!!
这题没必要优先队列优化,直接暴力写就好了。还没这么麻烦。
四、代码实现
#include<bits/stdc++.h>
using namespace std;
#define pb(x) push_back(x)
#define mk(x, y) make_pair(x, y)
#define pln() putchar('\n')
#define cln() (cout << '\n')
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
;
template <class T> inline void read(T &x) {
int t;
bool flag = false;
')) ;
';
+ t - ';
if(flag) x = -x;
}
int N, K1, K2;
int a[MAXN], b[MAXN];
LL sol2() {
|| K2 > ) {
, pos = -;
; i <= N; ++i) {
if(abs(a[i] - b[i]) > t1) {
t1 = abs(a[i] - b[i]);
pos = i;
}
}
)break;
if(a[pos] < b[pos]) {
&& K1 >= K2)a[pos]++, K1--;
&& K1 < K2)b[pos]--, K2--;
}
else if(a[pos] > b[pos]) {
&& K1 >= K2)a[pos]--, K1--;
&& K1 < K2)b[pos]++, K2--;
}
}
bool eq = true;
;i <= N && eq;++i)eq = a[i] == b[i];
) ^ (K2 & );
LL ans = ;
; i <= N; ++i)ans += LL(a[i] - b[i]) * LL(a[i] - b[i]);
return ans;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output2.txt", "w", stdout);
#endif // ONLINE_JUDGE
while(~scanf("%d%d%d", &N, &K1, &K2)) {
; i <= N; ++i)read(a[i]);
; i <= N; ++i)read(b[i]);
cout << sol2() << endl;
}
;
}
Codeforces Round #474-B(贪心)的更多相关文章
- codeforces round 474 pathwalks
题目传送门http://codeforces.com/contest/960/problem/F 4月25号期中考,答应过年级组长要考年排前3的,所以25号以前我就不搞竞赛了,期中考要考好. 有很多大 ...
- Divide by Zero 2018 and Codeforces Round #474 (Div. 1 + Div. 2, combined)
思路:把边看成点,然后每条边只能从下面的边转移过来,我们将边按照u为第一关键字,w为第二关键字排序,这样就能用线段树维护啦. #include<bits/stdc++.h> #define ...
- Divide by Zero 2018 and Codeforces Round #474 (Div. 1 + Div. 2, combined)G - Bandit Blues
题意:求满足条件的排列,1:从左往右会遇到a个比当前数大的数,(每次遇到更大的数会更换当前数)2.从右往左会遇到b个比当前数大的数. 题解:1-n的排列,n肯定是从左往右和从右往左的最后一个数. 考虑 ...
- 贪心+模拟 Codeforces Round #288 (Div. 2) C. Anya and Ghosts
题目传送门 /* 贪心 + 模拟:首先,如果蜡烛的燃烧时间小于最少需要点燃的蜡烛数一定是-1(蜡烛是1秒点一支), num[g[i]]记录每个鬼访问时已点燃的蜡烛数,若不够,tmp为还需要的蜡烛数, ...
- 贪心 Codeforces Round #288 (Div. 2) B. Anton and currency you all know
题目传送门 /* 题意:从前面找一个数字和末尾数字调换使得变成偶数且为最大 贪心:考虑两种情况:1. 有偶数且比末尾数字大(flag标记):2. 有偶数但都比末尾数字小(x位置标记) 仿照别人写的,再 ...
- 贪心 Codeforces Round #301 (Div. 2) B. School Marks
题目传送门 /* 贪心:首先要注意,y是中位数的要求:先把其他的都设置为1,那么最多有(n-1)/2个比y小的,cnt记录比y小的个数 num1是输出的1的个数,numy是除此之外的数都为y,此时的n ...
- Codeforces Round #412 (rated, Div. 2, base on VK Cup 2017 Round 3) A B C D 水 模拟 二分 贪心
A. Is it rated? time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- 贪心 Codeforces Round #297 (Div. 2) C. Ilya and Sticks
题目传送门 /* 题意:给n个棍子,组成的矩形面积和最大,每根棍子可以-1 贪心:排序后,相邻的进行比较,若可以读入x[p++],然后两两相乘相加就可以了 */ #include <cstdio ...
- 贪心 Codeforces Round #304 (Div. 2) B. Soldier and Badges
题目传送门 /* 题意:问最少增加多少值使变成递增序列 贪心:排序后,每一个值改为前一个值+1,有可能a[i-1] = a[i] + 1,所以要 >= */ #include <cstdi ...
- 贪心 Codeforces Round #303 (Div. 2) B. Equidistant String
题目传送门 /* 题意:找到一个字符串p,使得它和s,t的不同的总个数相同 贪心:假设p与s相同,奇偶变换赋值,当是偶数,则有答案 */ #include <cstdio> #includ ...
随机推荐
- eclipse中下载maven插件解决办法
https://blog.csdn.net/qq_30546099/article/details/71195446 解决Eclipse Maven插件的最佳方案 https://www.cnblog ...
- TCGA系列--TCGA长链非编码RNA的可视化工具TANRIC
http://ibl.mdanderson.org/tanric/_design/basic/index.html
- [原][osgearth]osgearthElvation中的一帧
create tile key contains 获取tile上的临界值 这里先获取层数的切份(下图) 然后使用xmin,xmax,ymin,ymax获取tile的四个点 再通过geoextent获取 ...
- [学习笔记]ST表
ST表 给定一个数列$a,O(nlogn)$预处理,$O(1)$查询数列在区间$[l,r]$的最值. 本文介绍求最大值. 实现 预处理 $st[i][j]$表示$max\{a_k\}(k\in[i,i ...
- hdu3951巴什博弈变型
参考博客:http://blog.csdn.net/sun897949163/article/details/50609070 特判一下m=1的情况,然后m!=1时,无论对手取多少,我只要取的让这条链 ...
- plsql安装图解
Plsqldev安装步骤
- (转)OAuth 2.0的设计思路
OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版. 本文对OAuth 2.0的设计思路和运行流程,做一个简明通俗的解释,主要参考材料为R ...
- HBase查询优化——持续更新
Scan:setBatch,setCaching,setCacheBlocks public void setBatch(int batch) public void setCaching(int c ...
- Tensorflow 模型文件结构、模型中Tensor查看
tensorflow训练后保存的模型主要包含两部分,一是网络结构的定义(网络图),二是网络结构里的参数值. 1. .meta文件 .meta 文件以 "protocol buffer&qu ...
- LOJ2319. 「NOIP2017」列队【线段树】
LINK 思路 神仙线段树 你考虑怎么样才能快速维护出答案 首先看看一条链怎么做? 首先很显然的思路是维护每个节点的是否出过队 然后对于重新入队的点 直接在后面暴力vector存一下就可以了 最核心的 ...