There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolling up(u), down (d), left (l) or right (r), but it won't stop rolling until hitting a wall. When the ball stops, it could choose the next direction. There is also a hole in this maze. The ball will drop into the hole if it rolls on to the hole.

Given the ball position, the hole position and the maze, find out how the ball could drop into the hole by moving the shortest distance. The distance is defined by the number of empty spaces traveled by the ball from the start position (excluded) to the hole (included). Output the moving directions by using 'u', 'd', 'l' and 'r'. Since there could be several different shortest ways, you should output the lexicographically smallest way. If the ball cannot reach the hole, output "impossible".

The maze is represented by a binary 2D array. 1 means the wall and 0 means the empty space. You may assume that the borders of the maze are all walls. The ball and the hole coordinates are represented by row and column indexes.

Example 1:

Input 1: a maze represented by a 2D array

0 0 0 0 0
1 1 0 0 1
0 0 0 0 0
0 1 0 0 1
0 1 0 0 0 Input 2: ball coordinate (rowBall, colBall) = (4, 3)
Input 3: hole coordinate (rowHole, colHole) = (0, 1) Output: "lul" Explanation: There are two shortest ways for the ball to drop into the hole.
The first way is left -> up -> left, represented by "lul".
The second way is up -> left, represented by 'ul'.
Both ways have shortest distance 6, but the first way is lexicographically smaller because 'l' < 'u'. So the output is "lul".

Example 2:

Input 1: a maze represented by a 2D array

0 0 0 0 0
1 1 0 0 1
0 0 0 0 0
0 1 0 0 1
0 1 0 0 0 Input 2: ball coordinate (rowBall, colBall) = (4, 3)
Input 3: hole coordinate (rowHole, colHole) = (3, 0) Output: "impossible" Explanation: The ball cannot reach the hole.

Note:

  1. There is only one ball and one hole in the maze.
  2. Both the ball and hole exist on an empty space, and they will not be at the same position initially.
  3. The given maze does not contain border (like the red rectangle in the example pictures), but you could assume the border of the maze are all walls.
  4. The maze contains at least 2 empty spaces, and the width and the height of the maze won't exceed 30.

这道题DEBUG,DE了半天,用了朴素的DFS,但还是超时在大case上了。果然已经超出了我的能力范围。

class Solution {
private:
int arr[][] = { { , },{ ,- },{ , },{ -, } };
vector<string> directions = { "r","l","d","u" };
public:
string findShortestWay(vector<vector<int>>& maze, vector<int>& ball, vector<int>& hole) {
vector<string> ret;
set<int> visited;
helper(maze, ball[], ball[], hole, ret, visited, "");
sort(ret.begin(), ret.end());
string tmpstr = "";
if (ret.empty()) return "impossible";
//for(auto str : ret)cout << str << endl;
for (int i = ; i < ret[].size(); i++) {
if (tmpstr.empty()) {
tmpstr += ret[][i];
}
else {
if (tmpstr.back() != ret[][i]) {
tmpstr += ret[][i];
}
}
}
return tmpstr;
}
void helper(vector<vector<int>>& maze, int x, int y, vector<int>& hole, vector<string>& ret, set<int>& visited, string path) {
int m = maze.size();
int n = maze[].size();
if (visited.count(x * n + y)) return;
if (!ret.empty() && path.size() > ret[].size()) return;
visited.insert(x*n + y);
for (int i = ; i<; i++) {
int dx = arr[i][];
int dy = arr[i][];
int tmpx, tmpy;
tmpx = x + dx;
tmpy = y + dy;
string tmppath = path;
while (tmpx < m && tmpx >= && tmpy<n && tmpy >= && maze[tmpx][tmpy] != ) {
tmppath += directions[i];
if (tmpx == hole[] && tmpy == hole[]) {
// cout << tmppath << endl;
if(ret.empty() || tmppath.size() < ret[].size()){
ret.clear();
ret.push_back(tmppath);
}
else if(tmppath.size() == ret[].size()){
ret.push_back(tmppath);
}
//ret.push_back(tmppath);
//visited.erase(x*n + y);
//return;
}
tmpx += dx; tmpy += dy;
}
tmpx -= dx; tmpy -= dy;
if (tmpx == x && tmpy == y) continue;
//cout << "tmp location " << tmpx << " and " << tmpy << endl;
//cout << path << endl;
helper(maze, tmpx, tmpy, hole, ret, visited, tmppath);
}
visited.erase(x*n + y);
}
};

下面是我的解法的改进版,调了两个小时...

核心在于初始化一个最大值数组,记录每一个小球能滞留的点,如果这个点的值被更新且小于当前的cost直接返回,因为之前经过这个点的时候,就已经是比现在小的cost,再搜索下去没有意义。

然后在找到终点之后,更新结果,AC的结果依旧惨不忍睹。

Runtime: 160 ms, faster than 8.20% of C++ online submissions for The Maze III.

class Solution {
private:
int arr[][] = { { , },{ ,- },{ , },{ -, } };
vector<string> directions = { "r","l","d","u" };
public:
string findShortestWay(vector<vector<int>>& maze, vector<int>& ball, vector<int>& hole) {
string ret = "";
vector<vector<int>> visited(maze.size(), vector<int>(maze[].size(), INT_MAX));
helper(maze, ball[], ball[], hole, ret, visited, "", );
if (ret.empty()) return "impossible";
return ret;
}
void helper(vector<vector<int>>& maze, int x, int y, vector<int>& hole, string& ret, vector<vector<int>>& visited, string path, int cost) {
int m = maze.size();
int n = maze[].size();
if (visited[x][y] >= cost) {
visited[x][y] = cost;
}
else {
return;
}
for (int i = ; i<; i++) {
int dx = arr[i][];
int dy = arr[i][];
int tmpx, tmpy, tmpcost = cost;
bool check = false, found = false, inloop = false;
tmpx = x;
tmpy = y;
string tmppath = path;
while (tmpx < m && tmpx >= && tmpy<n && tmpy >= && maze[tmpx][tmpy] != ) {
if (!check) {
tmppath += directions[i];
check = true;
}
if (tmpx == hole[] && tmpy == hole[]) {
if (visited[tmpx][tmpy] > tmpcost) {
visited[tmpx][tmpy] = tmpcost;
ret = tmppath;
}
else if(visited[tmpx][tmpy] == tmpcost && ret > tmppath){
ret = tmppath;
}
found = true;
}
tmpx += dx; tmpy += dy;
tmpcost++;
inloop = true;
}
if (inloop) {
tmpx -= dx;
tmpy -= dy;
tmpcost--;
}
if (tmpx == x && tmpy == y) continue;
//if (found) continue;
//cout << "tmp location " << tmpx << " and " << tmpy << endl;
//cout << path << endl;
helper(maze, tmpx, tmpy, hole, ret, visited, tmppath, tmpcost);
}
}
};

下面是网上的解法,用的是BFD。要求图上某一个点到已知点距离最近的方法就是BFS。但我觉得能存在更好的办法(Dijkstra)。

Runtime: 4 ms, faster than 100.00% of C++ online submissions for The Maze III.

#include "header.h"
class Solution {
public:
vector<vector<int>> dir = { { ,, },{ ,, },{ -,, },{ ,-, } };
vector<string> ds = { "d", "r", "u", "l" };
//d, r, u, l
string findShortestWay(vector<vector<int>>& maze, vector<int>& ball, vector<int>& hole) {
//2018-12-18 解决了maze I and maze II,我觉得本质上还是BFS的问题,这个时候的destination只是说变成了如果掉进了hole,那么就不在运动了这样
//哈哈哈哈哈哈一次AC!赞!
if (maze.empty()) return "";
int m = maze.size();
int n = maze[].size();
vector<vector<pair<int, string> >> check(m, vector<pair<int, string> >(n, { INT_MAX, "" }));
check[ball[]][ball[]] = { , "" };
queue<pair<int, int>> q;
q.push({ ball[], ball[] });
while (!q.empty()) {
int len = q.size();
while (len) {
auto p = q.front(); q.pop(); len--;
for (auto d : dir) {
int steps = ;
int i = p.first; int j = p.second;
while (i + d[] >= && i + d[] < m && j + d[] >= && j + d[] < n && !maze[i + d[]][j + d[]]) {
i = i + d[]; j = j + d[]; steps++;
if (i == hole[] && j == hole[]) { break; }
}
if (check[i][j].first > check[p.first][p.second].first + steps) {
check[i][j].first = check[p.first][p.second].first + steps;
check[i][j].second = check[p.first][p.second].second + ds[d[]];
q.push({ i, j });
}
else if (check[i][j].first == check[p.first][p.second].first + steps) {
if (check[i][j].second > check[p.first][p.second].second + ds[d[]]) {
q.push({ i, j });
check[i][j].second = check[p.first][p.second].second + ds[d[]];
}
}
}
}
}
return check[hole[]][hole[]].first == INT_MAX ? "impossible" : check[hole[]][hole[]].second;
}
};

最新文章

  1. 安装android studio报错Failed to install Intel HAXM.
  2. CSS3-box盒布局
  3. Light oj 1214-Large Division (同余定理)
  4. C++容器类对象函数參数问题
  5. bzoj1233
  6. 利用python建表
  7. eval(&quot;表达式&quot;)
  8. Kd-Tree算法原理和开源实现代码
  9. Linux重启后raid5的名字发生变化
  10. Java移位运算符详解实例
  11. 12 Django Rest Swagger生成api文档
  12. 从零开始编译Poco C++和VS2015环境配置
  13. Nio再学习之NIO的buffer缓冲区
  14. BZOJ3252攻略——长链剖分+贪心
  15. stimulus(6300✨)
  16. asp.net web form 的缺点
  17. SSM 全局异常
  18. vue-devtools 必备开发工具
  19. 180713-Spring之借助Redis设计访问计数器之扩展篇
  20. k8s的Rolling Update(滚动更新应用)

热门文章

  1. mysql sleep 死锁例子
  2. 使用cJSON解析JSON
  3. 部署jenkins+git
  4. 第八章 watch监听 83 名称案例-使用watch监听文本框数据的变化
  5. Python文件查找
  6. React使用JSX语法
  7. 【Python之路】特别篇--Python面向对象(进阶篇)
  8. jquery file选择器 语法
  9. 2018 南京预选赛 J Sum ( 欧拉素数筛 、Square-free Number、DP )
  10. js对象及初识面向对象(4)