hdoj1728【搜索的两种写法】

以前的一道题目,现在拿到总觉得是DFS,然后T掉就没什么想法了,很狗的看了以前的写法(以前还是看题解的AC的),是BFS,每次都要转弯,但是之前你的达到一种他走到了死路,所以才是不得不转弯,写法也是非常棒,预处理的转弯数是-1就可以达到一开始转弯的+1抵消。
DFS写法:
中间判断两个条件,如果是起点,不是起点,然后剪枝的话,就是有flag直接return,还有那个点不行也return,主要是转弯数不行或者点不是都要return。

#include<iostream>
#include<cstdio>
#include<math.h>
#include<queue>
#include<map>
#include<stdlib.h>
#include<string>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long LL;
#define PI acos(-1.0)

const int N=1e2+10;

bool vis[N][N];
int n,m;
char ma[N][N];
int sx,sy;
int ex,ey;
int k;

int dx[4]={1,-1,0,0};
int dy[4]={0,0,-1,1};
int flag;

struct asd{
    int x,y;
    int num;
};

bool JUDGE(int x,int y)
{
    if(x<=0||y<=0||x>n||y>m||ma[x][y]=='*')
        return 0;
    return 1;
}
queue<asd>q;

void BFS()
{
    while(!q.empty())
        q.pop();
    memset(vis,0,sizeof(vis));

    if(sx==ex&&sy==ey){
        flag=1;
        return;
    }

    asd now,ne;
    now.x=sx;now.y=sy;
    now.num=-1;
    vis[now.x][now.y]=1;
    q.push(now);

    while(!q.empty())
    {
        now=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            ne.x=dx[i]+now.x;
            ne.y=dy[i]+now.y;       //因为之前肯定是不能再走下去了,所以必须转弯。
            while(JUDGE(ne.x,ne.y)){       //然后一直在这个方向走走,走到不能走为止。
                if(!vis[ne.x][ne.y]){
                    ne.num=now.num+1;
                    vis[ne.x][ne.y]=1;
                    if(ne.x==ex&&ne.y==ey&&ne.num<=k){
                        flag=1;
                        return;
                    }
                    q.push(ne);
                }
                ne.x+=dx[i];
                ne.y+=dy[i];
            }
        }
    }
}


int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%s",ma[i]+1);
        scanf("%d",&k);
        scanf("%d%d%d%d",&sy,&sx,&ey,&ex);
        flag=0;
        BFS();
        if(flag)
            printf("yes
");
        else
            printf("no
");
    }
    return 0;
}

DFS写法

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PI;
typedef pair< PI, int> PII;
const double eps=1e-5;
const double pi=acos(-1.0);
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const int N=110;

char ma[N][N];
int vis[N][N];
int n,m,num;
int sx,sy,tx,ty,flag;
int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};

void dfs(int x,int y,int d)
{
    int i;
    if(vis[x][y]>num)
        return;
    if(vis[x][y]==num&&(x!=tx&&y!=ty))
        return;
    if(flag)
        return;

    if(x==tx&&y==ty){
        if(vis[x][y]<=num)
            flag=1;
        return;
    }
    for(i=0;i<4;i++){
        int xx=dx[i]+x;
        int yy=dy[i]+y;
        if(xx<0||yy<0||xx>=n||yy>=m||ma[xx][yy]=='*'||vis[xx][yy]<vis[x][y])
            continue;
        if(d!=-1&&i!=d&&vis[xx][yy]<vis[x][y]+1)
            continue;
        vis[xx][yy]=vis[x][y];
        if(d!=-1&&i!=d){
            vis[xx][yy]++;
        }
        dfs(xx,yy,i);
    }
}
int main()
{
    int T,i;
    cin>>T;
    while(T--){
        scanf("%d%d",&n,&m);
        for(i=0;i<n;i++){
            scanf("%s",ma[i]);
        }
        scanf("%d%d%d%d%d",&num,&sy,&sx,&ty,&tx);
        sy--;sx--;tx--;ty--;
        flag=0;
        memset(vis,1,sizeof(vis));
        vis[sx][sy]=0;
        dfs(sx,sy,-1);
        if(flag) printf("yes
");
        else printf("no
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934466.html