这是 meelo 原创的 IEEEXtreme极限编程大赛题解

Xtreme 10.0 - Mysterious Maze

题目来源 第10届IEEE极限编程大赛

https://www.hackerrank.com/contests/ieeextreme-challenges/challenges/mysterious-maze

There is a valuable treasure that is hidden below a complex maze. The maze is made of rooms and are square in shape, and a maze of size N will have N × N rooms with all of them closed initially. When a room is open, one can enter into it from any of its adjacent open rooms; two rooms are adjacent if they share a common wall.

The maze was built in a way that it opens itself by opening its rooms randomly. A maze is said to be open if there is at least one path from any one of the rooms facing the top of the maze to any room on the bottom side facing the treasure. Anyone, who attempts to enter the maze without being able to reach the treasure and return, will be cruelly killed by the maze.

The local government has spent years researching the maze and figured out a way to determine the sequence of rooms being opened in almost real time. Based on this data, the government has posed the following challenge, with a small percentage of the treasure to whomever solves the problem:

Given the sequence of room openings, determine when the maze becomes open, or if it remains closed throughout.

Input Format

Input begins with a single integer N, which denotes the size of maze.

All of the next lines (except the last one) denotes the sequence of the rooms the maze is opening. Each line contains 2 integers X and Y which denotes the row and column of the room opened by the maze. The last line just includes -1 and marks the end of input.

Constraints

1 <= XY <= N <= 1000

Output Format

Output a single integer R based on the final status of the maze. R denotes the number of room openings that occur before the maze first becomes open, or -1 if the maze remains closed.

Sample Input

4
1 4
2 3
3 2
4 3
4 1
2 1
1 1
-1

Sample Output

-1

Explanation

It is easy to understand if you plot the maze. The following is the state of the maze at the end of the inputs. Xindicates that a room is closed and O that a room is open. Note that there is no path from the top of the maze to the bottom of the maze.

O X X O
O X O X
X O X X
O X O X

Consider the second input sample (which is available if you click on the Run Code button):

4
1 4
2 3
3 2
4 3
4 1
2 1
1 1
3 1
3 4
2 2
-1

Below is a figure with the maze after 7 rooms are open. Note that there is no path from the top of the maze to the bottom of the maze, and therefore the maze is closed.

O X X O
O X O X
X O X X
O X O X

However, after 8th room is open, there is a path, as shown below:

O X X O
O X O X
O O X X
O X O X

Thus, the expected output is:

8

题目解析

这个题目像是一个搜索题,从上侧出发看是否能够搜索到下侧。搜索一次需要O(M^2)。每开一次门,都需要搜索1次。复杂度就到了10^9,铁定会超时。

迷宫是否连通,有点像两个节点是否是1类。判断两个节点是否是1类,可以用并查集嘛。

每打开一个房间,就将上下左右的房间合并成1类,需要O(log(M))的时间。

上侧和下侧分别建立一个虚拟节点,初始与第1行的房间和最后1行的房间相连。

每打开一个房间,判断上侧虚拟节点是否与下侧虚拟节点节点是否属于同一类。如果属于同一类,迷宫则被打通了。

总的复杂度为O(Nlog(M))。

程序

C++

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std; int find(vector<int> &parent, int x) {
int px;
if(parent[x] < ) {
px = x;
}
else {
px = find(parent, parent[x]);
parent[x] = px;
}
return px;
} void union_(vector<int> &parent, int x, int y) {
int px = find(parent, x);
int py = find(parent, y); if(px != py) { if(parent[px] < parent[py]) {
parent[px] += parent[py];
parent[py] = px;
}
else {
parent[py] += parent[px];
parent[px] = py;
}
}
} bool legal(int x, int y, int H) {
return (x >= && x <= H) && (y >= && y <=H);
} int pos2Index(int x, int y, int H) {
return (x-) * H + (y-);
} int main() {
int H;
cin >> H;
vector<int> parent(H*H+, -);
vector<vector<bool> > maze(H+, vector<bool>(H+, )); for(int i=; i<=H; i++) {
union_(parent, pos2Index(, i, H), H*H);
union_(parent, pos2Index(H, i, H), H*H+);
} int dir[][] = {{,}, {,-}, {,}, {-,}};
int count = ;
while(true) {
int x, y;
cin >> x;
if(x == -) {
cout << - << endl;
break;
}
cin >> y;
maze[x][y] = true;
for(int d=; d<; d++) {
int nx = x + dir[d][];
int ny = y + dir[d][]; if(legal(nx, ny, H) && maze[nx][ny]) {
union_(parent, pos2Index(x, y, H), pos2Index(nx, ny, H));
}
}
if(find(parent, H*H) == find(parent, H*H+)) {
cout << count;
break;
}
count++;
} return ;
}

博客中的文章均为 meelo 原创,请务必以链接形式注明 本文地址

IEEEXtreme 10.0 - Mysterious Maze的更多相关文章

  1. IEEEXtreme 10.0 - Mancala'h

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Mancala'h 题目来源 第10届IEEE极限编程大赛 https://www.hackerrank.c ...

  2. IEEEXtreme 10.0 - Inti Sets

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Inti Sets 题目来源 第10届IEEE极限编程大赛 https://www.hackerrank.c ...

  3. IEEEXtreme 10.0 - Painter's Dilemma

    这是 meelo 原创的 IEEEXtreme极限编程比赛题解 Xtreme 10.0 - Painter's Dilemma 题目来源 第10届IEEE极限编程大赛 https://www.hack ...

  4. IEEEXtreme 10.0 - Ellipse Art

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Ellipse Art 题目来源 第10届IEEE极限编程大赛 https://www.hackerrank ...

  5. IEEEXtreme 10.0 - Counting Molecules

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Counting Molecules 题目来源 第10届IEEE极限编程大赛 https://www.hac ...

  6. IEEEXtreme 10.0 - Checkers Challenge

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Checkers Challenge 题目来源 第10届IEEE极限编程大赛 https://www.hac ...

  7. IEEEXtreme 10.0 - Game of Stones

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Game of Stones 题目来源 第10届IEEE极限编程大赛 https://www.hackerr ...

  8. IEEEXtreme 10.0 - Playing 20 Questions with an Unreliable Friend

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Playing 20 Questions with an Unreliable Friend 题目来源 第1 ...

  9. IEEEXtreme 10.0 - Full Adder

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Full Adder 题目来源 第10届IEEE极限编程大赛 https://www.hackerrank. ...

随机推荐

  1. 【loj6059】Sum

    Portal --> loj6059 Solution ​​ 看过去第一反应是..大力数位dp!然后看了一眼数据范围... ​ 但是这没有什么关系!注意到我们不需要考虑前导零了,可以直接快乐dp ...

  2. 流媒体协议之JRTPLIB的使用20170919

    主要介绍JRTPLIB 2.x系列和3.x系列两种版本,它们的区别是2.x系列代码量少使用简单,但是只支持RFC 1889不支持RFC 3550,3.x支持RFC 3550,但代码量稍多,以及使用也稍 ...

  3. 图像处理之中值滤波介绍及C实现

    1 中值滤波概述 中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号平滑处理技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值. 中值滤波的基本原理是把数字图像或数字序 ...

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

  5. Git之git push不手动输入用户名和密码

    每次git push时都要输入用户名和密码,感觉很啰嗦,总结了网上的解决办法,有的发现不可以(原因未知),记录一个对我自己可用的方式,我的是windows. 1:添加环境变量 2:在%HOME%目录下 ...

  6. 「CSS」文本编排相关的CSS属性设置

    1.font-family:设置字体族. 格式为font-family:字体1,字体2,……,通用字体族|inherit. 通用字体族,是指一类相似的字体.W3C的CSS规则规定,要指定一个通用字体族 ...

  7. 前端PHP入门-019-内置函数之数学函数-很重要

    查看帮助文档为主 函数名 描述 实例 输入 输出 abs() 求绝对值 $abs = abs(-4.2); //4.2 数字 绝对值数字 ceil() 进一法取整 echo ceil(9.999); ...

  8. [DeeplearningAI笔记]卷积神经网络4.6-4.10神经网络风格迁移

    4.4特殊应用:人脸识别和神经网络风格转换 觉得有用的话,欢迎一起讨论相互学习~Follow Me 4.6什么是神经网络风格转换neural style transfer 将原图片作为内容图片Cont ...

  9. Ubuntu+NDK编译openssl

    为了Android上使用libcurl且支持HTTPS协议,需要依赖openssl,因此先来了解一下如何编译OpenSSL1.编译ARM下的共享库(默认的)我使用的是guardianproject的o ...

  10. base64解码

    网络传输经常用base64编码的数据,因此我们需要将其解码成正常字符集合. base64.h #ifdef __cplusplus extern "C" { #endif char ...