您的位置:首页 > 其它

HDU 1728 - 逃离迷宫

2017-09-22 15:08 405 查看
题目大意:中文题

解题思路:画十字来解题,看图就很清楚了。如图,第一个十字是起点为中心。然后,将除中心的都入队列,再画十字,之后的十字转弯次数为前一个加一(与之前的十字相同的线条已经记录过最少转弯次数)。





本来十字中心应该是按(1,1)(1,2)(1,3)(2,2)...顺序变化的,有些十字无法拓展所以没画图。要注意一个点,障碍物用于停止十字某个方向继续走,标记数组标记走过的点,所以标记数组不能特意用来判断障碍物停止继续走,起点的转弯次数为-1,这样第一个十字往四个方向都是0。

bfs ac代码:
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int t, m, n, vis[105][105], dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1}, x1, x2, Y1, y2, wonder;
char ch[105][105];
struct node{
int x, y;
int turn;
};
queue <node>qu;
void bfs()
{
while (!qu.empty())
qu.pop();
node temp, no;
temp.x = x1 - 1, temp.y = Y1 - 1;
temp.turn = -1;
if (x1 == x2 && Y1 == y2){
printf("yes\n");
return ;
}
memset(vis, 0, sizeof(vis));
qu.push(temp);
vis[x1-1][Y1-1] = 1;
while (!qu.empty()){
temp = qu.front();
qu.pop();
for (int i=0; i<4; i++){
no = temp;
no.x += dx[i];
no.y += dy[i];
no.turn = temp.turn + 1;
while (no.x >= 0 && no.x < m && no.y >= 0 && no.y < n
&& ch[no.x][no.y] != '*'){
if (!vis[no.x][no.y]){
if (no.x == x2-1 && no.y == y2-1 && no.turn <= wonder){
printf("yes\n");
return ;
}
vis[no.x][no.y] = 1;
qu.push(no);
}
no.x += dx[i];
no.y += dy[i];
}
}
}
printf("no\n");
return ;
}
int main()
{
scanf("%d", &t);
while (t--){
scanf("%d%d", &m, &n);
for (int i=0; i<m; i++)
scanf("%s", ch[i]);
scanf("%d%d%d%d%d", &wonder, &Y1, &x1, &y2, &x2);
bfs();
}
return 0;
}


dfs大体思路与bfs一致,需要多加一个剪枝。就是进入下一层是判断该点是否比记录的转弯次数少。剪纸应在进入下一层的判断,才是优化的正确道路。

dfs ac代码:
#include <iostream>
#include <cstring>
using namespace std;
int t, n, m, ex[2], goal[2], k, vis[105][105], flag;
int walk[4][2]={-1,0,1,0,0,-1,0,1}, turn[105][105];
char map[105][105];
void dfs(int center_x, int center_y, int cur)
{
int pos1, pos2;
if (cur > k || flag)
return ;
turn[center_x][center_y] = min(cur, turn[center_x][center_y]);
if (center_x == goal[0] && center_y == goal[1])
flag = 1;
vis[center_x][center_y] = 1;
for (int i=0; i<4; i++){
pos1 = center_x+walk[i][0], pos2 = center_y+walk[i][1];
while (map[pos1][pos2] == '.' && pos1 >= 1 && pos1 <= m 
&& pos2 >= 1 && pos2 <= n){
if (pos1 == goal[0]	&& pos2 == goal[1])
flag = 1;
if (pos1 >= 1 && pos1 <= m && pos2 >= 1 && 
pos2 <= n && cur+1 < turn[pos1][pos2])
dfs(pos1, pos2, cur+1);
pos1 += walk[i][0], pos2 += walk[i][1];
}
}
}
int main()
{
scanf("%d", &t);
while (t--){
scanf("%d%d", &m, &n);
flag = 0;
memset(vis, 0, sizeof(vis));
for (int i=1; i<=m; i++){
getchar();
for (int j=1; j<=n; j++){
scanf("%c", &map[i][j]);
turn[i][j] = 11;
}
}
scanf("%d%d%d%d%d", &k, &ex[1], &ex[0], &goal[1], &goal[0]);
turn[ex[0]][ex[1]] = 0;
dfs(ex[0], ex[1], 0);
if (flag)
printf("yes\n");
else
printf("no\n");
}
return 0;
} 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: