您的位置:首页 > 其它

hdu 1010 Tempter of the Bone

2015-07-19 16:43 447 查看
这个题一开始是想用BFS来做的,可是提交的时候并没有通过,然后仔细想了想,才发现题意要求是在时刻t恰好到达终点,不能提前,这样的话用BFS就不太好操作了,所以最后改用DFS进行操作。

用DFS的话就要用到剪枝,这里有两个剪枝:

①最优性剪枝:奇偶性剪枝。把原图按照x+y的奇偶性变成01矩阵,那么0和0,1和1之间一定距离偶数步,0和1之间一定距离奇数步,那么我们只需检查终点和当前点以及所剩步数的奇偶性就可以进行剪枝。

②可行性剪枝:当前点到达终点至少需要的步数为abs(x-en.x)+abs(y-en.y)如果当前所剩的步数小于这个值那么这个路线肯定是不可行的,剪枝。

要知道,一旦找到一条可行的路径后,就不需要在找下去了。对于人的移动我们可以通过dx和dy两个数组来进行控制,运用数组的好处在于,它可以之间通过一个循环来实现,减少了代码的变成复杂度。

#include <cstdio>
#include <cmath>
#include <iostream>

using namespace std;

struct note
{
int x,y;
}st,en;

int n,m,t,q;
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
char f[10][10];

void can(int x,int y,int i)
{
if (f[x][y]=='D') {if (i==t) q=1; return; }
if (i==t) return;
if (abs(en.x-x)+abs(en.y-y)>t-i) return;
if (abs((en.x+en.y)%2-(x+y)%2)!=(t-i)%2) return;
if (q==1) return;
f[x][y]='X';
for (int j=0;j<4;j++)
if ((x+dx[j]>=0)&&(x+dx[j]<n)&&(y+dy[j]>=0)&&(y+dy[j]<m)&&(f[x+dx[j]][y+dy[j]]!='X')) can(x+dx[j],y+dy[j],i+1);
f[x][y]='.';

}

int main()
{
while (scanf("%d%d%d",&n,&m,&t)!=EOF)
{
if (!n) break;
for (int i=0;i<n;i++)
{
scanf("%s",f[i]);
for (int j=0;j<m;j++)
{
if (f[i][j]=='S') {st.x=i; st.y=j;f[i][j]='X'; }
else if (f[i][j]=='D') {en.x=i; en.y=j; }
}
}
q=0;
can(st.x,st.y,0);
if (q) printf("YES\n"); else printf("NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: