3520. Step out of maze tju

/*
 这是暑假集训的第二场练习赛,这个题目给我第一印象就是DFS
 可是DFS恰是我的弱项,于是一直卡了好久,DFS到底没有用的路径没有return
 第二场比赛就只做了一道悲剧收场
 渐渐开始明白很多题目都有相似之处,比如这个就跟hdu1026很像,可是我一开始就没有
 想到BFS,如果以开始就想到BFS的话,我想我肯定可以做出来的
 第二天敲的时候还是有很多细节的地方需要注意的,居然PE 3次之多
 我相信通过暑假的学习我一定会更加成熟
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <stack>
using namespace std;

int map[105][105];
bool hash[105][105];
int dir[4][2] = { {0, 1}, {1, 0}, {-1, 0}, {0, -1} };
int n, m;
bool flag;
int pt[10000];
int len;

struct node
{
 int x;
 int y;
 int pre;
 int di;
}path[10000];
void BFS(int x, int y)
{
 queue<node> Q;
 node P, N;
 int t = 0;
 memset(hash, false, sizeof(hash));
 /*
 for(int i = 0; i < 4; i++)
 {
  P.x = x + dir[i][0];
  P.y = y + dir[i][1];
  P.pre = t;
  P.di = i;
  if(map[P.x][P.y] == 0)
  {
   hash[P.x][P.y] = true;
   Q.push(P);
  }
 }
 */
 P.x = x;
 P.y = y;
 P.pre = -1;
 Q.push(P);
 while(!Q.empty())
 {
  N = Q.front();
  path[t] = N;
  if(N.x < 1 || N.x > n || N.y < 1 || N.y > m)
  {
   stack <int> s;
   //int tt = N.pre;
   int d = N.di;
   s.push(d);
   int tt = N.pre;
   while(tt != 0)
   {
    s.push(d);
    tt = path[tt].pre;
    d = path[tt].di;
   }
   d = s.top();
   s.pop();
   if(d == 0)
    cout<<"R";
   else if(d == 1)
    cout<<"D";
   else if(d == 2)
    cout<<"U";
   else if(d == 3)
    cout<<"L";
   while(!s.empty())
   {
    d = s.top();
    s.pop();
    if(d == 0)
     cout<<" R";
    else if(d == 1)
     cout<<" D";
    else if(d == 2)
     cout<<" U";
    else if(d == 3)
     cout<<" L";
   }
   cout<<endl;
   return ;

  }

  Q.pop();
  for(int i = 0; i < 4; i++)
  {
   P.x = N.x + dir[i][0];
   P.y = N.y + dir[i][1];
   P.di = i;
   P.pre = t;
   if(!hash[P.x][P.y] && map[P.x][P.y] == 0)
   {
    Q.push(P);
    hash[P.x][P.y] = true;
   }
  }
  t++;
 }

}

void dfs(int x, int y, int di)
{
 
 if(x < 1 || x > n || y < 1 || y > m)
 {
  flag = true;
  return ;
 }
 
 for(int i = 0; i < 4; i++)
 {
  int x1 = x + dir[i][0];
  int y1 = y + dir[i][1];
  di = i;
  if(flag)
   return ;//比赛的时候这里忘记了加return ,输出了多余的路径,一直改不出来
  if(map[x1][y1] == 0)
  {
   map[x][y] = 1;
   dfs(x1, y1, di);
   if(flag)
   {
    pt[len++] = di;
    /*
    if(di == 0)
     cout<<"R ";
    else if(di == 1)
     cout<<"D ";
    else if(di == 2)
     cout<<"U ";
    else if(di == 3)
     cout<<"L ";
     */
   }
   map[x][y] = 0;
   
  }
 }
 
 
}

int main()
{
 int t;
 cin>>t;
 while(t--)
 {
  cin>>n>>m;
  memset(map, 0, sizeof(map));
  for(int i = 1; i <= n; i++)
  for(int j = 1; j <= m; j++)
   cin>>map[i][j];
  int x, y;
  cin>>x>>y;
  flag = false;
  len = 0;
  dfs(x, y, 0);
  if(pt[len - 1] == 0)
   cout<<"R";
  else if(pt[len - 1] == 1)
   cout<<"D";
  else if(pt[len -1 ] == 2)
   cout<<"U";
  else if(pt[len -1 ] == 3)
   cout<<"L";
  for(int i = len - 2; i >= 0; i--)
  {
   if(pt[i] == 0)
    cout<<" R";
   else if(pt[i] == 1)
    cout<<" D";
   else if(pt[i] == 2)
    cout<<" U";
   else if(pt[i] == 3)
    cout<<" L";
  }
  cout<<endl;
   
  //BFS(x, y);
 }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
``` # 定义 mark 方法,用于在迷宫中标记路径 def mark(self, path: List[MazeLocation]): # 遍历路径中的每个位置,将该位置标记为路径 for maze_location in path: self._grid[maze_location.row][maze_location.column] = Cell.PATH # 将起点和终点标记为起点和终点 self._grid[self.start.row][self.start.column] = Cell.START self._grid[self.goal.row][self.goal.column] = Cell.GOAL # 定义 clear 方法,用于清除迷宫中的标记 def clear(self, path: List[MazeLocation]): # 遍历路径中的每个位置,将该位置清空 for maze_location in path: self._grid[maze_location.row][maze_location.column] = Cell.EMPTY # 将起点和终点标记为起点和终点 self._grid[self.start.row][self.start.column] = Cell.START self._grid[self.goal.row][self.goal.column] = Cell.GOAL ``` 这段代码定义了两个方法,`mark` 和 `clear`,用于在迷宫中标记路径和清除标记。这两个方法都接受一个路径列表作为参数,该列表包含了从起点到终点的所有位置。 在 `mark` 方法中,我们遍历路径中的每个位置,将该位置标记为路径。具体地,我们将该位置对应的迷宫方格的值设置为 `Cell.PATH`。同时,我们还将起点和终点对应的方格的值设置为 `Cell.START` 和 `Cell.GOAL`,以便在标记路径后仍然能够看出起点和终点的位置。 在 `clear` 方法中,我们也遍历路径中的每个位置,将该位置清空,即将对应的迷宫方格的值设置为 `Cell.EMPTY`。同时,我们还将起点和终点对应的方格的值重新设置为 `Cell.START` 和 `Cell.GOAL`。这样就可以清除路径标记,恢复迷宫原来的状态了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值