题目来源:http://codeforces.com/gym/100134/attachments

题意:给一个迷宫,问是否存在一种方案,可以用一个正方形块,堵住从左上到右下的所有路径,输出坐标及正方形边长。

考虑到从起点到终点的方案可能会有很多,但可以确定所有路径集合的左右边界。而左右边界通常就是左手路径与右手路径。

关于左右手路径可以参考POJ 3083。

如果一个正方形既能够封锁左手路径,又能封锁右手路径,那么一定可以封锁所有路径。

可以枚举每一个点,作为正方形的左上角,再枚举正方形的边长。如果该正方形覆盖的区域既含有左手路径,又含有右手路径,同时没有障碍物,这样我们就可以认定该方案是合法的。

检验该方案的合法性可以采用前缀和的方法,即维护三个前缀和:障碍物的前缀和、左右手路径的前缀和。

枚举正方形的边长复杂度过高,可以采用二分查找的方法。二分能够同时覆盖左右手路径的边长的最小值,再检验该正方形区域内是否没有障碍物。这样复杂度即是O(n^2logn)。

注意正方形既不能覆盖起点,也不能覆盖终点。

代码:

#include <bits/stdc++.h>using namespace std;char a[1555][1555];
bool vis[1555][1555];
int n, m, suml[1555][1555], sumr[1555][1555], sumx[1555][1555];int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};void dfs(int x, int y, int p, int X) {vis[x][y] = 1;while (x != n || y != m) {if (X == 0) {for (int i = 0; i < 4; ++i) {int t = p + i + 3;t %= 4;if (x + dx[t] >= 1 && dx[t] <= n && y + dy[t] >= 1 && y + dy[t] <= m&& a[x + dx[t]][y + dy[t]] == '.') {x += dx[t];y += dy[t];p = t;break;}}} else {for (int i = p + 1; i > p - 3; --i) {int t = i + 4;t %= 4;if (x + dx[t] >= 1 && dx[t] <= n && y + dy[t] >= 1 && y + dy[t] <= m&& a[x + dx[t]][y + dy[t]] == '.') {x += dx[t];y += dy[t];p = t;break;}}}vis[x][y] = 1;}
}int _get(int x, int y) {int l = 1, r = min(n - x, m - y) + 1;if (suml[x + r - 1][y + r - 1] - suml[x - 1][y + r - 1] - suml[x + r - 1][y - 1] + suml[x - 1][y - 1] == 0 ||sumr[x + r - 1][y + r - 1] - sumr[x - 1][y + r - 1] - sumr[x + r - 1][y - 1] + sumr[x - 1][y - 1] == 0)return 1e9;while (l < r) {int m = (l + r) >> 1;if (suml[x + m - 1][y + m - 1] - suml[x - 1][y + m - 1] - suml[x + m - 1][y - 1] + suml[x - 1][y - 1] > 0 &&sumr[x + m - 1][y + m - 1] - sumr[x - 1][y + m - 1] - sumr[x + m - 1][y - 1] + sumr[x - 1][y - 1] > 0)r = m;else l = m + 1;}if (sumx[x + l - 1][y + l - 1] - sumx[x - 1][y + l - 1] - sumx[x + l - 1][y - 1] + sumx[x - 1][y - 1] == 0) {if (x + l - 1 == n && y + l - 1 == m)return 1e9;else return l;}return 1e9;
}int main() {freopen("labyrinth.in", "r", stdin);freopen("labyrinth.out", "w", stdout);ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin >> m >> n;for (int i = 1; i <= n; ++i) {for (int j = 1; j <= m; ++j) {cin >> a[i][j];sumx[i][j] = sumx[i - 1][j] + sumx[i][j - 1] - sumx[i - 1][j - 1];if (a[i][j] == '#')sumx[i][j]++;}}memset(vis, 0, sizeof vis);dfs(1, 1, 1, 0);for (int i = 1; i <= n; ++i) {for (int j = 1; j <= m; ++j) {suml[i][j] = suml[i - 1][j] + suml[i][j - 1] - suml[i - 1][j - 1];if (vis[i][j])suml[i][j]++;}}memset(vis, 0, sizeof vis);dfs(1, 1, 2, 2);for (int i = 1; i <= n; ++i) {for (int j = 1; j <= m; ++j) {sumr[i][j] = sumr[i - 1][j] + sumr[i][j - 1] - sumr[i - 1][j - 1];if (vis[i][j])sumr[i][j]++;}}int ans = 1e9, x, y;for (int i = 1; i <= n; ++i) {for (int j = 1; j <= m; ++j) {if ((i != 1 || j != 1) && (i != n || j != m) && a[i][j] == '.') {int t = _get(i, j);if (t < ans) {ans = t;x = i;y = j;}}}}if (ans > 1e7)cout << "Impossible" << endl;else cout << ans << ' ' << y << ' ' << x << endl;return 0;
}

Gym 100134L - Labyrinth of the Minotaur相关推荐

  1. BZOJ3808 : Neerc2012 Labyrinth of the Minotaur

    左上角和右下角不四连通等价于左下角和右上角八连通 枚举正方形的左上角,先二分出最大的边长,使得里面不含障碍物 然后再二分出最小的边长,使得两部分连通,用前缀和判断 这题WA了好久-一直对拍都没问题-于 ...

  2. 3808: Neerc2012 Labyrinth of the Minotaur

    题目大意:给你一个n*m的格子,有些格子有障碍,要你找到一个最小的正方形格子,使得这个正方形没有覆盖障碍且去掉这个正方形后(1,1)与(n,m)就不连通了 n<=1500 m<=1500 ...

  3. 2016.03.04,英语,《Vocabulary Builder》Unit 04

    vor: 来自拉丁动词vorare,指to eat,-ivorous指吃某种食物的eater.carn肉,肉欲+vore吃→吃肉的:carnival狂欢节,谢肉节voracious a 狼吞虎咽的(v ...

  4. 紫书《算法竞赛入门经典》

    紫书<算法竞赛入门经典>题目一览 第3章 数组和字符串(例题) UVA 272 TEX Quotes UVA 10082 WERTYU UVA 401 Palindromes UVA 34 ...

  5. rabbitmq java 测试_RabbitMQ 简单测试

    RabbitMQ 测试 RabbitMQ 基于Erlang 实现, 客户端可以用Python | Java | Ruby | PHP | C# | Javascript | Go等语言来实现.这里做个 ...

  6. B - Labyrinth Gym - 102798B

    B - Labyrinth Gym - 102798B 题意: n * m的地图,有k个障碍物,给你起点到终点,从起点到终点的最短距离 1<=n,m<=200000 nm<=2000 ...

  7. Ubuntu下常用强化学习实验环境搭建(MuJoCo, OpenAI Gym, rllab, DeepMind Lab, TORCS, PySC2)

    原文地址:http://blog.csdn.net/jinzhuojun/article/details/77144590 和其它的机器学习方向一样,强化学习(Reinforcement Learni ...

  8. 【25.93%】【676D】Theseus and labyrinth

    time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  9. Codeforces 676D Theseus and labyrinth 模拟+bfs

    D. Theseus and labyrinth time limit per test 3 seconds memory limit per test 256 megabytes input sta ...

最新文章

  1. 腾讯优图吴永坚:迈向深度学习,我们面临模型训练与推荐的双重考验
  2. 使用pytorch构建2D和3D人脸比对库(使用face-alignment)
  3. KETTLE数据上传
  4. 仿京东首页上侧导航左侧地址栏布局(1)
  5. 关于Window操作系统中对Oracle的性能监控
  6. Python学习笔记__10.4章 进程VS线程
  7. Spark精华问答 | Spark 会替代Hadoop 吗?
  8. 【离散数学】集合的划分与覆盖
  9. Java里的阻塞队列
  10. docker 网桥冲突了解决
  11. ajax请求url最大长度,针对较长的URL的400BAD请求(ajax)
  12. MOOC 浙江大学C语言翁恺(第一、二章 满分答案)
  13. 关于游戏开发流程解析
  14. c++字符串逆序输出
  15. python蒙特卡洛模拟return_python蒙特卡洛脚本模拟—挑战者号爆炸概率
  16. 如何用Python做日历?
  17. 全名k歌自定义图文链接(卡片)
  18. 怎么用计算机的计算器转换进位制,计算机进制换算(进制转换计算器)
  19. 【Leetcode】[190] 颠倒二进制位
  20. 中国十大垃圾软件网站

热门文章

  1. 爬取电影网站链接并进入网盘通过验证码下载的python(未完成)
  2. Django项目连接MongoDB的三种方法
  3. 【缺氧本体】火箭发射自动化模块
  4. ASP.NET控件中回车自动跳转至下指定控件
  5. 英伟达GTC 公告确认这是一个互联的多芯片世界
  6. 9 个超实用的 JavaScript 原生插件工具
  7. Python可视化:中国环保股上市公司市值Top20强
  8. 版本管理:RCS之命令基础篇
  9. 解决raw.githubusercontent.com地址DNS污染的方法参考
  10. Win11打开安卓子系统步骤,所遇到的问题,以及解决办法