【2018.9.20】JOI 2017 Final T3「JOIOI 王国 / The Kingdom of JOIOI」
题目描述
JOIOI 王国是一个 $H$ 行 $W$ 列的长方形网格,每个 $1\times 1$ 的子网格都是一个正方形的小区块。为了提高管理效率,我们决定把整个国家划分成两个省 $JOI$ 和 $IOI$ 。
我们定义,两个同省的区块互相连接,意为从一个区块出发,不用穿过任何一个不同省的区块,就可以移动到另一个区块。有公共边的区块间可以任意移动。
我们不希望划分得过于复杂,因此划分方案需满足以下条件:
- 区块不能被分割为两半,一半属 $JOI$ 省,一半属 $IOI$ 省。
- 每个省必须包含至少一个区块,每个区块也必须属于且只属于其中一个省。
- 同省的任意两个小区块互相连接。
- 对于每一行/列,如果我们将这一行/列单独取出,这一行/列里同省的任意两个区块互相连接。这一行/列内的所有区块可以全部属于一个省。
现给出所有区块的海拔,第 $i$ 行第 $j$ 列的区块的海拔为 $A_{i,j}$。设 JOI 省内各区块海拔的极差(最大值减去最小值) 为 $R_{JOI}$,IOI 省内各区块海拔的极差为 $R_{IOI}$。在划分后,省内的交流有望更加活跃。但如果两个区块的海拔差太大,两地间的交通会很不方便。 因此,理想的划分方案是 $\max(R_{JOI}, R_{IOI})$ 尽可能小。
你的任务是求出 $max(R_{JOI}, R_{IOI})$ 至少为多大。
输入格式
第一行,两个整数 $H,W$,用空格分隔。
在接下来的 HHH 行中,第 $i$ 行有 $W$ 个整数 $A_{i,1}, A_{i, 2}, \ldots, A_{i, W}$,用空格分隔。
输入的所有数的含义见题目描述。
输出格式
一行,一个整数,表示 $max(R_{JOI}, R_{IOI})$ 可能的最小值。
样例
样例输入 1
4 4
1 12 6 11
11 10 2 14
10 1 9 20
4 17 19 10
样例输出 1
11
样例解释 1
在这组样例中,一种理想方案长这样。下图中,$J$ 表示该区块属于 $JOI$ 省,$I$ 表示该区块属于 $IOI$ 省。
| $J$ | $J$ | $J$ | $I$ |
| $J$ | $J$ | $J$ | $I$ |
| $J$ | $J$ | $I$ | $I$ |
| $J$ | $I$ | $I$ | $I$ |
注意下述方案不符合第四条原则,将第三列单独取出时,两个 $I$ 不能互相连接。
| $J$ | $J$ | $I$ | $I$ |
| $J$ | $J$ | $J$ | $I$ |
| $J$ | $J$ | $I$ | $I$ |
| $J$ | $I$ | $I$ | $I$ |
样例输入 2
8 6
23 23 10 11 16 21
15 26 19 28 19 20
25 26 28 16 15 11
11 8 19 11 15 24
14 19 15 14 24 11
10 8 11 7 6 14
23 5 19 23 17 17
18 11 21 14 20 16
样例输出 2
18
数据范围与提示
对于 $15\%$ 的数据,$H, W\leqslant 10$。
对于另外 $45\%$ 的数据,$H, W\leqslant 200$。
对于所有数据,$2\leqslant H, W\leqslant 2000, A_{i,j}\leqslant 10^9(1\leqslant i\leqslant H, 1\leqslant j\leqslant W)$。
上网搜这JOI的题,一篇题解都没找到,好尬啊,只好回日本 JOI2017 原网站看了半天日语题解,日语水平菜头皮发麻。
看看$N,M$,乘起来共有400w个数,再看看答案的值域,$[0, 10^9(max-min)]$。
好像可以二分答案并$n^2$判断?
于是我们只需要再知道怎么判断分割是否可行。
其实,题目说的比较含蓄,整个地图划分的两个省其实都类似于旋转三角:

原因是这两条:
- 同省的任意两个小区块互相连接。
- 对于每一行/列,如果我们将这一行/列单独取出,这一行/列里同省的任意两个区块互相连接。这一行/列内的所有区块可以全部属于一个省
所以判断就比较方便了。
我们可以先找出海拔的最小值$AllMin$和最大值$AllMax$。
然后二分答案与海拔最小值的差(这样更好,我直接二分答案然后莫名被卡)$x$。
我们就要判断现在能否划分出两个类似于上图的三角,如果能就缩小答案,如果不能就增大答案。
那么让一块的最大值$\leq AllMin+x$,一块的最小值$\geq AllMax-x$,依次判断上述四种情况是否有一种满足即可。
比如让红色省区的最大值$\leq AllMin+x$,以第二张图为例,只需要从第一行开始在每行中遍历。如果遍历到 第一个海拔$\geq$最大值的地方 或者 超过上一行划分的红色省区右端的地方 就停(这一格不划入红色省区),转到下一行即可。否则将该格划入红色省区。
然后每行右边没划的地方自然全给蓝色省区,再判一下蓝色省区的最小值是否$\geq AllMax-x$就行了。
其它情况类似。
时间复杂度$O(H*W*log(AllMax-AllMin))$。
#include <cstdio>
#include <algorithm>
using namespace std; int H, W, A[][];
int gmin, gmax; bool check(int th)
{
int sep = ;
for (int i = ; i < H; ++i) {
for (int j = ; j < W; ++j) {
if (A[i][j] < gmax - th) {
sep = max(sep, j + );
}
}
for (int j = ; j < W; ++j) {
if (gmin + th < A[i][j]) {
if (j < sep) return false;
}
}
}
return true;
}
void flip_row()
{
for (int i = ; i < H / ; ++i) {
for (int j = ; j < W; ++j) {
swap(A[i][j], A[H - - i][j]);
}
}
}
void flip_col()
{
for (int i = ; i < H; ++i) {
for (int j = ; j < W / ; ++j) {
swap(A[i][j], A[i][W - - j]);
}
}
}
int solve()
{
int lo = , hi = gmax - gmin;
while (lo < hi) {
int mid = (lo + hi) / ;
if (check(mid)) {
hi = mid;
} else {
lo = mid + ;
}
}
return lo;
}
int main()
{
scanf("%d%d", &H, &W);
for (int i = ; i < H; ++i) {
for (int j = ; j < W; ++j) {
scanf("%d", &(A[i][j]));
}
} gmin = gmax = A[][];
for (int i = ; i < H; ++i) {
for (int j = ; j < W; ++j) {
gmin = min(gmin, A[i][j]);
gmax = max(gmax, A[i][j]);
}
} //翻转三次,得到四种情况
int ret = solve();
flip_row();
ret = min(ret, solve());
flip_col();
ret = min(ret, solve());
flip_row();
ret = min(ret, solve());
printf("%d\n", ret);
return ;
}
【2018.9.20】JOI 2017 Final T3「JOIOI 王国 / The Kingdom of JOIOI」的更多相关文章
- 【2018.9.20】JOI 2017 Final T2「準急電車 / Semiexpress」
题目描述 JOI 铁路公司是 JOI 国唯一的铁路公司. 在某条铁路沿线共有 $N$ 座车站,依次编号为 $1...N$. 目前,正在服役的车次按照运行速度可分为两类:高速电车(简称快车)与普通电车( ...
- 「JOI 2017 Final」JOIOI 王国
「JOI 2017 Final」JOIOI 王国 题目描述 题目译自 JOI 2017 Final T3「 JOIOI 王国 / The Kingdom of JOIOI」 JOIOI 王国是一个 H ...
- Libre OJ P2332「JOI 2017 Final」焚风现象【差分思想】By cellur925
题目传送门 这道题开始看起来会很晕...\(qwq\).首先我们要明确题目中的海拔&&温度.温度是受海拔影响的,每次改变的是海拔,我们求的是温度. 我们开始读入的时候便可以处理出开始\ ...
- loj 2336「JOI 2017 Final」绳
loj 首先,所有位置最多被染色一次,因为要染多次的话,还不如一开始就染成最终的颜色.并且你可以一开始就染好色 因为最终长度为2,那么如果染完后这个序列可以被折完,那么首先最多只有两种颜色,还有就是要 ...
- loj#2334 「JOI 2017 Final」JOIOI 王国
分析 二分答案 判断左上角是否满足 为了覆盖所有范围 我们依次把右下角,左上角,右上角移动到左上角 代码 #include<bits/stdc++.h> using namespace s ...
- loj#2333 「JOI 2017 Final」准高速电车
分析 我们发现到达一个点一定是先快车再准快车再慢车 于是快车将1-n分为多个区间 每次取出每个区间当前能到达的点的数量 选剩余时间贡献最大的的一个取得贡献并且再能到达的最远点建立准快车 代码 #inc ...
- loj#2332 「JOI 2017 Final」焚风现象
分析 我们发现改变一个区间实际上只有两个端点的贡献变换 代码 #include<bits/stdc++.h> using namespace std; #define int long l ...
- 「JOI 2017 Final」绳
题意 loj 做法 首先我们观察到最后能折起来的充要条件是: 只有两个颜色,除首尾外,所有颜色块内的数量为偶数 因为为偶数,我们进一步推论: 所有颜色块起始位置奇偶性相同 然后因为增与减都会有相同花费 ...
- [JOI 2017 Final] 足球 (建图,最短路)
题面 题解 我们可以总结出球的两种状态,要么自己飞,要么在球员脚下被带飞. 自己飞的情况下,他只能单向直线运动,每一步代价为A,被带飞可以乱走,每一步代价为C. 从自己飞到被带飞需要一个距离自己最近的 ...
随机推荐
- codevs 1146 ISBN号码
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题目描述 Description 每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字.1 ...
- Codeforces Round #317 (Div. 2) C Lengthening Sticks (组合,数学)
一个合法的三角形的充要条件是a<b+c,其中a为最长的一边,可以考虑找出所有不满足的情况然后用总方案减去不合法的情况. 对于一个给定的总长度tl(一定要分完,因为是枚举tl,不分配的长度已经考虑 ...
- const、let、var的区别
const不能从字面上来理解,他不能修改的是栈内存在的值和地址. 使用const声明的是常量,在后面出现的代码中不能再修改该常量的值. 怎么理解栈内存在的值和地址呢?就要从javascript的类型说 ...
- Python 类变量,成员变量,静态变量,局部变量
局部 class TestClass(object): val1 = 100 def __init__(self): self.val2 = 200 def fcn(self,val = 400): ...
- msys2 使用指定boost
pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-openssl mingw-w64- ...
- Paxos算法与Zookeeper分析,zab (zk)raft协议(etcd) 8. 与Galera及MySQL Group replication的比较
mit 分布式论文集 https://github.com/feixiao/Distributed-Systems wiki上描述的几种都明白了就出师了 raft 和 zab 是类似的,都是1.先选举 ...
- 带你进入Angular js的大门
首先需要指出什么是angular js,其实说白了angular js就是Javascript的一个类库,我们使用这个类库可以很容易的创建web页面.双向绑定是angular js其中的一个重要特征, ...
- Ukulele 常用和弦
- MySQL丨01丨数据库基本概念
以前记录数据可能很少也很简单,比如说老王借了老李半斤肉,这样的数据老李直接就写到墙上就行了. 后来数据多了人们就以表格的方式开始记录,写到一张A4纸上,比如学生的档案,有表头和序号等. 表头里有姓名. ...
- Linux菜鸟起飞之路【四】绝对路径、相对路径及常用目录
一.绝对路径与相对路径 Linux操作系统中存在着两种路径:绝对路径和相对路径.我们在访问文件或文件夹的时候,其实都是通过路径来操作的.两种路径在实际操作中能起到同等的作用. 在开始具体介绍之前,我们 ...