JOIOI王国 - 二分+贪心
题面

题解
通过一句经典的话“最大值的最小值” 我判断它是二分题,
不难发现,整个图形中两个省的分界线是一条单调不递减或单调不递增的折线。
而且,越到后来它的最大值只会越来越大,最小值只会越来越小,极差只会越来越大。
所以如果我们把ans上界定下来了,我们就可以贪心的让它其中一个区域的值在 [maxa - ans , maxa] 的灰色地带发展,然后判断另一个区域是否合法。由于另一个区域的点数越少越好,所以在灰色地带要尽量发展得广。
我们只能先定义一个 p 表示当前行两省的分界, 然后在第一行尽量扩展得远,下一行在 [0 , p]之间扩展得远,这样不仅可以让另一个区域的点更少,而且可以让下一行有更大的发展空间。
其它的贪心方法就不行了,所以分别行数从小到大和从大到小各枚举一次,然后做个左右对称再来。
CODE
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#define LL long long
using namespace std;
inline LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();}
while(s >= '0' && s <= '9'){x = x * 10 + s - '0';s = getchar();}
return x * f;
}
LL n,m,i,j,s,o,k,flag = 0;
LL a[2005][2005];
int b[2005],c[2005];
int x1 = 1,x2 = 1,y1 = 1,y2 = 1;
LL maxl[2005][2005];
LL maxr[2005][2005];
LL minl[2005][2005];
LL minr[2005][2005];
LL ans = 1e18;
bool check(LL mid) {
LL minn = a[x1][y1] - mid;
// cout<<minn<<endl;
LL p = m,mi1 = 0x7f7f7f7f,mi2 = 0x7f7f7f7f,ma1=0,ma2=0;
for(int i = 1;i <= n;i ++) {
int pp = p;
for(int j = 0;j <= pp;j ++) {
if(minl[i][j] >= minn) {
p = j;
}
}
mi1 = min(mi1,minl[i][p]);
ma1 = max(ma1,maxl[i][p]);
mi2 = min(mi2,minr[i][p + 1]);
ma2 = max(ma2,maxr[i][p + 1]);
}
// cout<<"ok1"<<endl;
if(max(ma1 - mi1,ma2 - mi2) <= mid) return 1;
p = m,mi1 = 0x7f7f7f7f,mi2 = 0x7f7f7f7f,ma1=0,ma2=0;
for(int i = n;i > 0;i --) {
int pp = p;
for(int j = 0;j <= pp;j ++) {
if(minl[i][j] >= minn) {
p = j;
}
}
mi1 = min(mi1,minl[i][p]);
ma1 = max(ma1,maxl[i][p]);
mi2 = min(mi2,minr[i][p + 1]);
ma2 = max(ma2,maxr[i][p + 1]);
}
// cout<<"ok2"<<endl;
if(max(ma1 - mi1,ma2 - mi2) <= mid) return 1;
p = 0,mi1 = 0x7f7f7f7f,mi2 = 0x7f7f7f7f,ma1=0,ma2=0;
for(int i = 1;i <= n;i ++) {
int pp = p;
for(int j = m;j >= pp;j --) {
if(minr[i][j + 1] >= minn) {
p = j;
}
}
mi1 = min(mi1,minl[i][p]);
ma1 = max(ma1,maxl[i][p]);
mi2 = min(mi2,minr[i][p + 1]);
ma2 = max(ma2,maxr[i][p + 1]);
}
// cout<<"ok3"<<endl;
if(max(ma1 - mi1,ma2 - mi2) <= mid) return 1;
p = 0,mi1 = 0x7f7f7f7f,mi2 = 0x7f7f7f7f,ma1=0,ma2=0;
for(int i = n;i > 0;i --) {
int pp = p;
for(int j = m;j >= pp;j --) {
if(minr[i][j + 1] >= minn) {
p = j;
}
}
// printf("p---%d\n",p);
mi1 = min(mi1,minl[i][p]);
ma1 = max(ma1,maxl[i][p]);
mi2 = min(mi2,minr[i][p + 1]);
ma2 = max(ma2,maxr[i][p + 1]);
}
// cout<<"ok4"<<endl;
if(max(ma1 - mi1,ma2 - mi2) <= mid) return 1;
return 0;
}
LL solve(LL l,LL r) {
// printf("%lld %lld\n",l,r);
if(l >= r - 1) {
if(check(l)) return l;
return r;
}
LL mid = (l + r) / 2;
if(check(mid)) return solve(l,mid);
return solve(mid,r);
}
int main() {
n = read();m = read();
for(int i = 1;i <= n;i ++) {
minl[i][0] = 1e18;
for(int j = 1;j <= m;j ++) {
a[i][j] = read();
if(a[i][j] > a[x1][y1]) x1 = i,y1 = j;
if(a[i][j] < a[x2][y2]) x2 = i,y2 = j;
minl[i][j] = min(minl[i][j - 1],a[i][j]);
maxl[i][j] = max(maxl[i][j - 1],a[i][j]);
}
minr[i][m + 1] = 1e18;
for(int j = m;j > 0;j --) {
minr[i][j] = min(minr[i][j + 1],a[i][j]);
maxr[i][j] = max(maxr[i][j + 1],a[i][j]);
}
// for(int j = 1;j <= m;j ++) {
// printf("%lld ",minr[i][j]);
// }putchar('\n');
}
printf("%lld\n",solve(0,a[x1][y1] - a[x2][y2]));
return 0;
}
JOIOI王国 - 二分+贪心的更多相关文章
- 「JOI 2017 Final」JOIOI 王国
「JOI 2017 Final」JOIOI 王国 题目描述 题目译自 JOI 2017 Final T3「 JOIOI 王国 / The Kingdom of JOIOI」 JOIOI 王国是一个 H ...
- 「题解」JOIOI 王国
「题解」JOIOI 王国 题目描述 考场思考 正解 题目描述 点这里 考场思考 因为时间不太够了,直接一上来就着手暴力.但是本人太菜,居然暴力爆 000 ,然后当场自闭- 一气之下,发现对 60pts ...
- Codeforces Gym 100231B Intervals 线段树+二分+贪心
Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...
- 2016-2017 ACM-ICPC CHINA-Final Ice Cream Tower 二分+贪心
/** 题目:2016-2017 ACM-ICPC CHINA-Final Ice Cream Tower 链接:http://codeforces.com/gym/101194 题意:给n个木块,堆 ...
- 【bzoj2097】[Usaco2010 Dec]Exercise 奶牛健美操 二分+贪心
题目描述 Farmer John为了保持奶牛们的健康,让可怜的奶牛们不停在牧场之间 的小路上奔跑.这些奶牛的路径集合可以被表示成一个点集和一些连接 两个顶点的双向路,使得每对点之间恰好有一条简单路径. ...
- Codeforces_732D_(二分贪心)
D. Exams time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...
- CF732D Exams 二分 贪心
思路:二分+贪心 提交次数:10次以上 错因:刚开始以为二分(边界,$+1or-1$)写错了,调了半天,后来才发现是$ck()$写错了.开始只判了最后是否小于零,而应该中间一旦小于零就$return\ ...
- $CF949D\ Curfew$ 二分/贪心
正解:二分/贪心 解题报告: 传送门$QwQ$ 首先这里是二分还是蛮显然的?考虑二分那个最大值,然后先保证一个老师是合法的再看另一个老师那里是否合法就成$QwQ$. 发现不太会搞这个合不合法的所以咕了 ...
- $bzoj2067\ szn$ 二分+贪心
正解:二分+贪心 解题报告: 传送门$QwQ$ 题目大意就说有一棵树,然后要用若干条线覆盖所有边且不能重叠.问最少要用几条线,在用线最少的前提下最长的线最短是多长. 昂首先最少用多少条线这个还是蛮$e ...
随机推荐
- Linux文本搜索及截取操作
Linux文本搜索及截取操作 cat 查看 grep 搜索 awk 截取 查看dna-server.xml 文件的内容 [root@localhost servers]# cat cwag9002/w ...
- C# List转String的办法
2022年5月28日 初始记录 代码: String.Join(",", List.ToArray());
- SpringCloudAlibaba学习(解决SpringBoot初始化以及Nginx启动出错问题)
微服务强调每个服务都是单独的数据库 在不使用微服务的情况下可以采用分布式架构,通过Template来调用远程的Rest接口 但这种方式维护起来很麻烦,而且有很多弊端. 一.环境搭建 1.首先搭建Spr ...
- 一条update语句到底加了多少锁?带你深入理解底层原理
迎面走来了你的面试官,身穿格子衫,挺着啤酒肚,发际线严重后移的中年男子. 手拿泡着枸杞的保温杯,胳膊夹着MacBook,MacBook上还贴着公司标语:"我爱加班". 面试开始,直 ...
- python:**也不过如此嘛,这不也被我采集下来啦~
前言 嗨喽!大家好呀,这里是小熊猫 知识点: 基本流程 fiddler抓包 开发环境: python 3.8 运行代码 pycharm 2021.2 辅助敲代码 requests 第三方模块 如果安装 ...
- MYSQL中IF IN语句
以下代码摘自后台管理系统中的一部分SQL语句: 当取数状态为1或2时,才展示取数时间,否则,取数时间展示为空 当申报状态为2.3.4或5时,才展示申报时间,否则,申报时间展示为空 select A.Q ...
- java SWT中Label实时刷新当前时间
同样最近在开发swt的一个项目,业务中的一个功能模块类似百度网盘的上传进度条 0/80. 即已上传0个,总共80个.效果展示要的就是实时刷新,2/80呀,15/80呀,针对这个,就有了这篇文章. 下面 ...
- idea显示 RunDashboard ,多个启动项时列表显示
在.idea(项目所在文件夹中)下的workspace.xml文件中找到 <component name="RunDashboard"> 标签,然后添加如下节点 < ...
- 避坑手册 | JAVA编码中容易踩坑的十大陷阱
JAVA编码中存在一些容易被人忽视的陷阱,稍不留神可能就会跌落其中,给项目的稳定运行埋下隐患.此外,这些陷阱也是面试的时候面试官比较喜欢问的问题. 本文对这些陷阱进行了统一的整理,让你知道应该如何避免 ...
- CF1042E Vasya and Magic Matrix 题解
题目链接 思路分析 看到题目中 \(n,m \leq 1000\) ,故直接考虑 \(O(n^2)\) 级别做法. 我们先把所有的点按照 \(val\) 值从小到大排序,这样的话二维问题变成序列问题. ...