hd1010

这道题一开始做成dfs,求最短路径去了。后来发现要在t时刻时恰好到达,所以要用bfs。然后学到一个奇偶剪枝的技巧。

现假设起点为(sx,sy),终点为(ex,ey),给定t步恰好走到终点,


s
       

|
       

|
       

|
       

+




e

如图所示(“|”竖走,“—”横走,“+”转弯),易证abs(ex-sx)+abs(ey-sy)为此问题类中任意情况下,起点到终点的最短步数,记做step,此处step1=8;


s



 
 


+
 

|

+
     

|
       

+




e

如图,为一般情况下非最短路径的任意走法举例,step2=14;

step2-step1=6,偏移路径为6,偶数(易证);

推广之,若 t-[abs(ex-sx)+abs(ey-sy)] 结果为非偶数(奇数),则无法在t步恰好到达;

#include <iostream>
#include <cmath>
using namespace std;

int vis[8][8];
char map[8][8];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int n,m,t,sx,sy,gx,gy,flag;
#define judge(x,y) vis[x][y]==0&&map[x][y]!=‘X‘&&0<=x&&x<n&&0<=y&&y<m//一开始写成==‘.‘ 导致走不到(gx,gy)因为它是‘D’

void init()
{
    flag=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            vis[i][j]=0;

            cin>>map[i][j];

            if(map[i][j]==‘S‘)
            {
                sx=i;sy=j;
            }
            if(map[i][j]==‘D‘)
            {
                gx=i;gy=j;
            }
        }
}

void bfs(int x,int y,int tt)
{
    if(tt>t) return ;//剪枝
    if(flag==1) return ;

    if(x==gx&&y==gy&&tt==t)
    {
        flag=1;
    }

    for(int i=0;i<4;i++)
    {
        int nx=x+dx[i];
        int ny=y+dy[i];
        if(judge(nx,ny))
        {
            vis[nx][ny]=1;
            bfs(nx,ny,tt+1);
            vis[nx][ny]=0;
        }
    }
}
int main()
{

    while(cin>>n>>m>>t)
    {
        if(n==0&&m==0&&t==0)
            break;
        init();
        //奇偶剪枝*****
        int p=abs(sx-gx)+abs(sy-gy)+t;
        if(p%2==1||p-2*t>0)
        //if(abs(sx-gx)+abs(sy-gy)>t||(sx+gx+sy+gy+t)%2==1)
            cout<<"NO"<<endl;
        else
        {
            vis[sx][sy]=1;//没有记录(sx,sy)为已走过 WA了一次
            bfs(sx,sy,0);
            if(flag)
                cout<<"YES"<<endl;
            else
                cout<<"NO"<<endl;
        }
    }
    return  0;
}

  

反思:

①The input is terminated with three 0‘s. This test case is not to be processed   可以用  &&(n+m+k)  即n、m、k同时为0。

②#define judge(x,y) 里面 ,map[x][y]!=‘X‘,一开始写成==‘.‘, 导致走不到(gx,gy),因为它是‘D’。

③没有记录(sx,sy)为已走过 WA了一次

④p那个地方可能出现负的,所以用abs(sx-gx)+abs(sy-gy)和t相加而不是相减;

时间: 2024-10-06 13:12:05

hd1010的相关文章