一、题目链接

  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(贪心)的更多相关文章

  1. codeforces round 474 pathwalks

    题目传送门http://codeforces.com/contest/960/problem/F 4月25号期中考,答应过年级组长要考年排前3的,所以25号以前我就不搞竞赛了,期中考要考好. 有很多大 ...

  2. Divide by Zero 2018 and Codeforces Round #474 (Div. 1 + Div. 2, combined)

    思路:把边看成点,然后每条边只能从下面的边转移过来,我们将边按照u为第一关键字,w为第二关键字排序,这样就能用线段树维护啦. #include<bits/stdc++.h> #define ...

  3. Divide by Zero 2018 and Codeforces Round #474 (Div. 1 + Div. 2, combined)G - Bandit Blues

    题意:求满足条件的排列,1:从左往右会遇到a个比当前数大的数,(每次遇到更大的数会更换当前数)2.从右往左会遇到b个比当前数大的数. 题解:1-n的排列,n肯定是从左往右和从右往左的最后一个数. 考虑 ...

  4. 贪心+模拟 Codeforces Round #288 (Div. 2) C. Anya and Ghosts

    题目传送门 /* 贪心 + 模拟:首先,如果蜡烛的燃烧时间小于最少需要点燃的蜡烛数一定是-1(蜡烛是1秒点一支), num[g[i]]记录每个鬼访问时已点燃的蜡烛数,若不够,tmp为还需要的蜡烛数, ...

  5. 贪心 Codeforces Round #288 (Div. 2) B. Anton and currency you all know

    题目传送门 /* 题意:从前面找一个数字和末尾数字调换使得变成偶数且为最大 贪心:考虑两种情况:1. 有偶数且比末尾数字大(flag标记):2. 有偶数但都比末尾数字小(x位置标记) 仿照别人写的,再 ...

  6. 贪心 Codeforces Round #301 (Div. 2) B. School Marks

    题目传送门 /* 贪心:首先要注意,y是中位数的要求:先把其他的都设置为1,那么最多有(n-1)/2个比y小的,cnt记录比y小的个数 num1是输出的1的个数,numy是除此之外的数都为y,此时的n ...

  7. 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 ...

  8. 贪心 Codeforces Round #297 (Div. 2) C. Ilya and Sticks

    题目传送门 /* 题意:给n个棍子,组成的矩形面积和最大,每根棍子可以-1 贪心:排序后,相邻的进行比较,若可以读入x[p++],然后两两相乘相加就可以了 */ #include <cstdio ...

  9. 贪心 Codeforces Round #304 (Div. 2) B. Soldier and Badges

    题目传送门 /* 题意:问最少增加多少值使变成递增序列 贪心:排序后,每一个值改为前一个值+1,有可能a[i-1] = a[i] + 1,所以要 >= */ #include <cstdi ...

  10. 贪心 Codeforces Round #303 (Div. 2) B. Equidistant String

    题目传送门 /* 题意:找到一个字符串p,使得它和s,t的不同的总个数相同 贪心:假设p与s相同,奇偶变换赋值,当是偶数,则有答案 */ #include <cstdio> #includ ...

随机推荐

  1. AngularJS Toaster

    AngularJS Toaster 是 AngularJS 的扩展,实现了无堵塞消息通知.该项目对 Toastr 进行改造,原来的 Toastr 只支持 jQuery,而 AngularJS Toas ...

  2. Android之自定义控件实现天气温度折线图和饼状图

    以前写了个天气的APP,最近把他更新了一个版本,就抽取其中的天气温度折现图这个功能写了这篇博客,来与大家分享,希望对你有所帮助. 效果如图: 代码: MainActivity.Java /**** * ...

  3. hadoo异常——org.apache.hadoop.security.UserGroupInformation: PriviledgedActionException

    2013-08-20 10:36:17,728 INFO org.apache.hadoop.http.HttpServer: listener.getLocalPort() returned 500 ...

  4. echarta3 北京,上海地图

    1.首先你得到echarts官网下载js,建议下载完整代码,这样你就很容易根据我的路径找到beijing.js 2.把echarts.js和beijingi.js根据你的路径引对,然后就可以copy我 ...

  5. python模块之ConfigParser: 用python解析配置文件

    在程序中使用配置文件来灵活的配置一些参数是一件很常见的事情,配置文件的解析并不复杂,在python里更是如此,在官方发布的库中就包含有做这件事情的库,那就是ConfigParser,这里简单的做一些介 ...

  6. 浅析使用vue-router实现前端路由的两种方式

    关于vue-router 由于最近的项目中一直在使用vue,所以前端路由方案也是使用的官方路由vue-router,之前在angularJS项目中也是用过UI-router,感觉大同小异,不过很显然v ...

  7. svn版本管理与上线

    1.1 SVN介绍 1.1.1 什么是SVN(Subversion)? Svn(subversion)是近年来崛起的非常优秀的版本管理工具,与CVS管理工具一样,SVN是一个跨平台的开源的版本控制系统 ...

  8. Linux磁盘分区扩容

    随着业务的增长,aliyun数据盘容量可能无法满足数据存储的需要,这时可以使用“”磁盘扩容“”功能扩容数据盘. 本文以一个SSD云盘的数据盘和一个运行Ubuntu 16..4 64位的 ECS 实例为 ...

  9. BZOJ4012: [HNOI2015]开店【动态点分治】

    Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...

  10. Codeforces 148B: Escape

    题目链接:http://codeforces.com/problemset/problem/148/B 题意:公主从龙的洞穴中逃跑,公主的速度为vp,龙的速度为vd,在公主逃跑时间t时,龙发现公主逃跑 ...