題目鏈結
problem description
給定乙個m × n (m行, n列)的迷宮,迷宮中有兩個位置,gloria想從迷宮的乙個位置走到另外乙個位置,當然迷宮中有些地方是空地,gloria可以穿越,有些地方是障礙,她必須繞行,從迷宮的乙個位置,只能走到與它相鄰的4個位置中,當然在行走過程中,gloria不能走到迷宮外面去。令人頭痛的是,gloria是個沒什麼方向感的人,因此,她在行走過程中,不能轉太多彎了,否則她會暈倒的。我們假定給定的兩個位置都是空地,初始時,gloria所面向的方向未定,她可以選擇4個方向的任何乙個出發,而不算成一次轉彎。gloria能從乙個位置走到另外乙個位置嗎?
input
第1行為乙個整數t (1 ≤ t ≤ 100),表示測試資料的個數,接下來為t組測試資料,每組測試資料中,
第1行為兩個整數m, n (1 ≤ m, n ≤ 100),分別表示迷宮的行數和列數,接下來m行,每行包括n個字元,其中字元'.'表示該位置為空地,字元'*'表示該位置為障礙,輸入資料中只有這兩種字元,每組測試資料的最後一行為5個整數k, x1, y1, x2, y2 (1 ≤ k ≤ 10, 1 ≤ x1, x2 ≤ n, 1 ≤ y1, y2 ≤ m),其中k表示gloria最多能轉的彎數,(x1, y1), (x2, y2)表示兩個位置,其中x1,x2對應列,y1, y2對應行。
output
每組測試資料對應為一行,若gloria能從乙個位置走到另外乙個位置,輸出「yes」,否則輸出「no」。
sample input
2 5 5 ...** *.**. ..... ..... *.... 1 1 1 1 3 5 5 ...** *.**. ..... ..... *.... 2 1 1 1 3sample output
no yes題解:可以用dfs搜尋所有情況判斷是否有滿足題目條件的。定義乙個結構體node,成員變數有x,y表示行列座標,dir表示方向,count表示轉彎次數。bool dfs(node node)就表示滿足的node節點能否走到終點。從起點開始判斷,只需要四次迴圈,走上下左右四個方向,任何乙個方向dfs返回true就說明可以走到終點,否則不能。
每次dfs乙個節點時,需要先判斷是否是牆,是否越界,轉彎次數是否超標。最重要的是需要剪枝,如果dfs到某個node時,之前可能已經搜過該node了,就需要判斷是否需要剪枝,如果判斷出之前搜過該點,並且之前搜該店時最小的轉彎次數比本次搜該點的轉彎次數小(有點繞),那麼現在去搜這個點肯定肯定走不到終點,所以需要直接return false來剪枝,沒有這步剪枝應該會tle。
為了容易看明白些,**有些可以省略簡寫的地方沒有省略,比如搜4個方向可以for迴圈,這裡就直接貼了4遍**。
#include #include #include #define top 0
#define bottom 1
#define left 2
#define right 3
using namespace std;
int m,n; // 地圖行列數
int max; // 最多轉彎次數
char map[105][105]; // 存放地圖,從1開始
// 避免走回頭路,要滿足該點visited且轉彎次數更大
bool visited[105][105]; //每個點訪問記錄
int visitedcount[105][105]; // 記錄每個點訪問時的轉彎次數
struct node
}start,end; // 起始點和目標點
/** * 深度優先搜尋
*/bool dfs(node node) else
}if (x < 1 || y < 1 || x > m || y > n)
if (node.count > max)
if (x == end.x && y == end.y)
/** 該點可以走
*/visited[x][y] = true;
visitedcount[x][y] = node.count;
node temp;
// 走四個方向
// 上
temp.x = x - 1,temp.y = y,temp.dir = top;
temp.count = (node.dir == top ? node.count : node.count+1);
// 起點特判
if (node.x == start.x && node.y == start.y)
temp.count = 0;
if (dfs(temp) == true)
return true;
// 下
temp.x = x + 1,temp.y = y,temp.dir = bottom;
temp.count = (node.dir == bottom ? node.count : node.count+1);
if (node.x == start.x && node.y == start.y)
temp.count = 0;
if (dfs(temp) == true)
return true;
// 左
temp.x = x,temp.y = y - 1,temp.dir = left;
temp.count = (node.dir == left ? node.count : node.count+1);
if (node.x == start.x && node.y == start.y)
temp.count = 0;
if (dfs(temp) == true)
return true;
// 右
temp.x = x,temp.y = y + 1,temp.dir = right;
temp.count = (node.dir == right ? node.count : node.count+1);
if (node.x == start.x && node.y == start.y)
temp.count = 0;
if (dfs(temp) == true)
return true;
return false;
}int main() else
}return 0;
}
HDOJ 1728 逃離迷宮(DFS)
problem description 給定乙個m n m行,n列 的迷宮,迷宮中有兩個位置,gloria想從迷宮的乙個位置走到另外乙個位置,當然迷宮中有些地方是空地,gloria可以穿越,有些地方是障礙,她必須繞行,從迷宮的乙個位置,只能走到與它相鄰的4個位置中,當然在行走過程中,gloria不能...
Hdoj 1728 逃離迷宮
problem description 給定乙個m n m行,n列 的迷宮,迷宮中有兩個位置,gloria想從迷宮的乙個位置走到另外乙個位置,當然迷宮中有些地方是空地,gloria可以穿越,有些地方是障礙,她必須繞行,從迷宮的乙個位置,只能走到與它相鄰的4個位置中,當然在行走過程中,gloria不能...
HDU1728逃離迷宮(dfs 剪枝)
解題思路 一開始覺得是深搜模板題也沒多想,結果wa,發現輸入的出發點和終點都是先列再行 坑 改了下,又wa。起初的book陣列我用來存結點是否走過,原來這裡出bug了,題意是讓我們找結點是否能在k次轉彎內抵達。這裡存在著可能這個結點上次搜超過k次了,但是我們把他標記走過,等到下次經過這卻沒超過k次,...