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 ...
随机推荐
- python 字符串压缩
import zlib s = b'witch which has which witches wrist watch' print(len(s)) t = zlib.compress(s) prin ...
- Redis高级命令操作大全--推荐
redis安装和使用 redis安装 wget http://download.redis.io/redis-stable.tar.gz tar zxvf redis-stable.tar.gz cd ...
- 如何基于Netty处理粘包、拆包问题?
涉及到相关重要组件: ByteToMessageDecoder MessageToMessageDecoder 这两个组件都实现了ChannelInboundHandler接口,这说明这两个组件都是用 ...
- Android之网络图片加载的5种基本方式
学了这么久,最近有空把自己用到过的网络加载图片的方式总结了出来,与大家共享,希望对你们有帮助. 此博客包含Android 5种基本的加载网络图片方式,包括普通加载HttpURLConnection.H ...
- Android 之WebView实现下拉刷新和其他相关刷新功能
最近项目中需要用到WebView下拉刷新的功能,经过查找资料终于完成了此功能,现在拿出来和大家分享一下.希望对大家有所帮助. 效果如下图: 代码: activity.xml <?xml ve ...
- hdu——1873(优先队列)
看病要排队 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- SGU 156 Strange Graph 欧拉回路,思路,汉密尔顿回路 难度:3
http://acm.sgu.ru/problem.php?contest=0&problem=156 这道题有两种点 1. 度数>2 在团中的点,一定连接一个度数为2的点 2. 度数等 ...
- hdu5575
题解: 每一次最短的那块板合并 先装水到溢出 然后合并 代码: #include<cstdio> #include<cstring> #include<algorithm ...
- 根据马甲、应用商店、统计每天的注册量,要求可以根据选择马甲和app,马甲和appstrore和user_login不同表问题
这个马甲属于一个表,appStore另一张表,用户登录表,主要操作的就是这三个表. 我这里的马甲和app的id都与用户登录表中的channel对应,在channel存放的是majiaId + “|” ...
- BZOJ3293: [Cqoi2011]分金币(数学)
3293: [Cqoi2011]分金币 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1596 Solved: 969[Submit][Status ...