HDU 1728 逃离迷宫

http://acm.hdu.edu.cn/showproblem.php?pid=1728

题意: 还是走迷宫,只是这次有个转弯次数的要求。

这道题目看到后,我首先想到的是用DFS去搜,自己感觉DFS搜索到的应该就是最小的转弯次数了。然后么,TLE了几把,真伤啊。囧。问了下学长,他和我说因为是100*100的格子,如果不理想的话可能要搜索会很高的(囧,好吧)然后他建议我用BFS写,嗯,本来 他的意思是BFS在搜索的过程中把那些转弯道的入队列,写的时候不是很懂,最后很鄙视自己得用了一步一步的搜索方式把这题A了。。。。(ORZ)

/*
*     Danceonly
*/

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long LL;

#define MAX(a,b) (a > b ? a : b)
#define MIN(a,b) (a < b ? a : b)


struct node
{
      int x,y;
      int d;
      int s;
}q[100005],e;
int N,M,sx,sy,ex,ey,K;
int maze[105][105],vis[105][105],Map[105][105];
int dir[4][2] = {1,0,0,1,-1,0,0,-1};
int cnt,flag,Find;
bool BFS()
{
      int tail,head,x,y,d,s;
      head = tail = 0;
      q[head].x = sx;
      q[head].y = sy;
      q[head].d = -1;
      q[head].s = -1;
      while (head <= tail)
      {
            x = q[head].x;
            y = q[head].y;
            d = q[head].d;
            s = q[head].s;
            for (int i=0;i<4;i++)
            {
                  e.x = x + dir[i][0];
                  e.y = y + dir[i][1];
                  if (maze[e.x][e.y] == 0 || e.x <= 0 || e.x > N || e.y <= 0 || e.y > M )continue ;  //不能去这个点
                  e.s = s + (d != i);
                  e.d = i;
                  if (vis[e.x][e.y] == 0)      //说明没有访问过
                  {
                        q[++tail] = e;
                        Map[e.x][e.y] = e.s;
                  }
                  else if (Map[e.x][e.y] <= s)continue ;
                  else
                  {
                        q[++tail] = e;
                        Map[e.x][e.y] = e.s;
                  }
                  vis[e.x][e.y] = 1;
                  if (e.x == ex && e.y == ey && q[tail].s <= K)
                  {
                        return 1;
                  }
            }
            head ++ ;
      }
      return 0;
}
void show()
{
      for (int i=1;i<=N;i++)
      {
            for (int j=1;j<=M;j++)
                  printf("%d ",maze[i][j]);
            printf("\n");
      }
}
int main()
{
      int T;
      scanf("%d",&T);
      while (T--)
      {
            scanf("%d%d",&N,&M);
            memset(vis,0,sizeof(vis));
            memset(maze,0,sizeof(maze));
            memset(Map,-1,sizeof(Map));
            for (int i=1;i<=N;i++)
            {
                  char ss[105];
                  scanf("%s",ss);
                  for (int j=0;j<M;j++)
                        if (ss[j] == '.')maze[i][j+1] = 1;
            }
            //show();
            scanf("%d%d%d%d%d",&K,&sy,&sx,&ey,&ex);
            if (sx == ex && sy == ey){printf("yes\n");continue ;}
            maze[sx][sy] = maze[ex][ey] = 1;
            vis[sx][sy] = 1;
            if (BFS())printf("yes\n");
            else printf("no\n");
      }
      return 0;
}


转载于:https://www.cnblogs.com/cnwsycf/p/3335378.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值