HDU

来源:互联网 发布:ccd视觉编程软件 编辑:程序博客网 时间:2024/06/18 09:35

题意:给出n*m个矩阵,‘S’代表出发点,‘D’是门,门只在第t秒,‘X’是路障,不能通过,‘.’可以通过,问能否在t秒时到达‘D’。而且‘S’,‘D’在图中都只有一个。
分析:dfs,一开始想成了bfs,不可以,bfs尝试后就已经被标记了,不能把标记去掉,dfs在尝试后发现走不通可以去掉标记。还有个就是需要剪枝,奇偶性剪枝,如果终点到起点的距离是奇数,但时间是偶数,或者时间是奇数,距离是偶数,都不能到达。如果不剪,则会TL。
代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<iomanip>#include<cmath>#include<vector>#include<set>#include<queue>#define INF 0x3f3f3f3fusing namespace std;int n,m,t;int x3,y3,x2,y2;int vis[105][105];char Map[105][105];int flag=0;int d[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//方向数组bool dfs(int x,int y,int cur){    if(x==x2&&y==y2&&cur==t)  //到达条件,如果到达,flag为1;    {        flag=1;        return true;    }       if(x==x2&&y==y2)      //返回套件        return true;        //四个方向尝试         for(int i=0;i<4;i++)        {            int dx=x+d[i][0];            int dy=y+d[i][1];            if(dx>=0&&dx<n&&dy>=0&&dy<m&&!vis[dx][dy]&&Map[dx][dy]!='X')            {                vis[dx][dy]=1;//标记为已走                dfs(dx,dy,cur+1);                vis[dx][dy]=0;//如果退回来,则去掉标记            }        }}int main(){    while(scanf("%d%d%d",&n,&m,&t)!=EOF&&n&&m&&t)    {        for(int i=0;i<n;i++)            scanf("%s",Map[i]);  //找到起点和终点        for(int i=0;i<n;i++)            for(int j=0;j<m;j++)        {            if(Map[i][j]=='S')            {                x3=i;                y3=j;            }            if(Map[i][j]=='D')            {                x2=i;                y2=j;            }        }        memset(vis,0,sizeof(vis));        if(abs(x2-x3)+abs(y2-y3)>t||(abs(x2-x3)+abs(y2-y3))%2!=t%2)//剪枝        cout<<"NO"<<endl;        else        {            vis[x3][y3]=1;        flag=0;        dfs(x3,y3,0);        if(flag)            cout<<"YES"<<endl;        else            cout<<"NO"<<endl;        }    }}