广搜的一个题

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <iostream>
using namespace std;

const int N = 999999;

struct point {
int x,y;
}s[20000];

char map[110][110];
int turn[110][110];
int n,m,x2,y2,k1,k;
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};

void dfs(int x,int y,int dis)
{
    int i,tx,ty;
    //什么时候返回
    if(x==x2&&y==y2&&turn[x][y]<=k)
    {
        k1=1;
        return;
    }
    //不能返回的情况
    if(turn[x][y]>k)
        return;
    //剪枝啊~
    if(x!=x2&&y!=y2&&turn[x][y]==k)
        return;
    //向上下左右遍历移动~
    for (int i=0;i<4;i++)
    {
        tx=x+dx[i];
        ty=y+dy[i];
        if(tx<=0 ||ty<=0||tx>m||ty>n|| map[tx][ty]=='*')//这些地方不能移动
            continue;//再找

    if(turn[tx][ty]<turn[x][y])//上次走到tx,ty用时比这次小,继续回去找
        continue;
    //以下两个if语句用来剪枝
    if(dis!=-1 && i!=dis &&turn[tx][ty]<turn[x][y]+1)
        continue;
    if(dis!=-1 && i!=dis)
        turn[tx][ty]=turn[x][y]+1;
    else
        turn[tx][ty]=turn[x][y];
    map[tx][ty]='*';//遇到墙,用dfs换方向
    dfs(tx,ty,i);
    map[tx][ty]='.';//不是墙
    if(k1)
        return;
    }
}

int main()
{
    int i,j,t,x1,y1;
    cin>>t;
    while(t--)
    {
        cin>>m>>n;
        for (i=1;i<=m;i++)
        {
            for (j=1;j<=n;j++)
            {
                cin>>map[i][j];
            }
                cin>>k>>y1>>x1>>y2>>x2;
                memset(turn,N,sizeof(turn));
                k1=0;
                turn[x1][y1]=0;
                dfs(x1,y1,-1);
                if(k1) cout<<"yes"<<endl;
                else cout<<"no"<<endl;

        }
        return 0;
    }
}

猜你喜欢

转载自www.cnblogs.com/jzzb/p/9359864.html
今日推荐