您的位置:首页 > 其它

hdu 1010 Tempter of the Bone(DFS + 奇偶剪枝 + 路径剪枝)

2017-09-23 13:52 489 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010

题目大意:给出一个N*M的迷宫,‘X’代表墙,‘.’代表路,'S'代表起点,'D'代表终点,每走一步消耗一个单位时间,问能否恰好在T个单位时间,从起点走到终点。

分析:如果只是简单的DFS肯定会超时,所以一定要加上剪枝,最重要的两个技巧就是奇偶剪枝和路径剪枝。

           奇偶剪枝:假设起点为(sx,sy),终点为(dx,dy),给定t步恰好到达终点,则当extra = t - abs(dx - ex)- abs(dy - ey)为偶数时,能恰好在t步到达终点;反之, 则不能。

           路径剪枝:计算出迷宫内墙的数量为wall,当N * M - wall <= T 时,则不可能恰好在T到达终点。

           其他只要注意边界等细节就可以了。

           奇偶剪枝证明:https://baike.baidu.com/item/%E5%A5%87%E5%81%B6%E5%89%AA%E6%9E%9D/10385689?fr=aladdin

ac代码

#include<cstdio>
#include<cmath>

int N, M, T;
char maze[10][10];
int wall;
int sx, sy, dx, dy;
int flag;
int pos[4][2] = {0, -1, 0, 1, 1, 0, -1, 0};

void dfs(int x, int y, int step)
{
//if(x > N || y > M || x < 0 || y < 0)return;
if(flag)return;
if(x == dx && y == dy && step == T)
{
flag = 1;
return;
}
if(step >= T)return;
int ans = fabs(dx - x) + fabs(dy - y);
int res = T - step - ans;
if(res < 0 || res % 2)return;
for(int i = 0; i < 4; i++)
{
if(x + pos[i][0] >= 0 && x + pos[i][0] < N && y + pos[i][1] >= 0 && y + pos[i][1] < M && maze[x + pos[i][0]][y + pos[i][1]] != 'X')
{
maze[x + pos[i][0]][y + pos[i][1]] = 'X';
dfs(x + pos[i][0], y + pos[i][1], step + 1);
maze[x + pos[i][0]][y + pos[i][1]] = '.';
}
}
return;
}

int main()
{
while(scanf("%d %d %d", &N, &M, &T))
{
wall = 0;
flag = 0;
if(N == 0 && M == 0 && T == 0)break;
for(int i = 0; i < N; i++)
scanf("%s", maze[i]);
for(int i = 0; i < N; i++)
for(int j = 0; j < M; j++)
{
if(maze[i][j] == 'X')wall++;
if(maze[i][j] == 'S')
{
sx = i;
sy = j;
}
if(maze[i][j] == 'D')
{
dx = i;
dy = j;
}
}
if(N * M - wall <= T)flag = 0;
else
{
flag = 0;
maze[sx][sy] = 'X';
dfs(sx, sy, 0);
}
if(flag)printf("YES\n");
else printf("NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: