徐老师的回家之路(广搜最难题)

本文介绍了一种结合广度优先搜索(BFS)算法与特殊传送门机制的问题解决方法。通过使用结构体存储点的信息和魔法阵对应位置,实现对迷宫问题的有效求解,避免了死循环,并详细阐述了解题思路及代码实现。


这道题是广搜经典题目,比普通的广搜题的举一反三的一点多了一个传送门。所以在这里要用一个数组('A'~'Z')来存储相对应的2个传送门相对应的位置,然后只要特判当走到传送门时,就找到另一个对应的传送门,传送过去即可。在这里要用一个mf[]数组来存储'A'~'Z'中一一对应的魔法阵。x1,y1,x2,y2分别代表2个对应魔法阵的位置。存储进mf数组中的逻辑:如果x1,y1==0,则说明x1,y1没有存储,所以把(i,j)存进x1,y1中。否则,就存进x2,y2中。而在碰到魔法阵时,则要判断当时的mf[a[t2.x][t2.y]].x1是否等于t2.x;mf[a[t2.x][t2.y]].x2是否等于t2.y,如果都是,则说明该传送门对应的传送门的位置应是(mf[a[t2.x][t2.y]].x2,mf[a[t2.x][t2.y]].y2),否则,说明该传送门对应的传送门的位置应是(mf[a[t2.x][t2.y]].x1,mf[a[t2.x][t2.y]].y1)。

还有一点,就是为了避免死循环(2个传送门一直相互传),所以要用一个py来存储走了多少个点了。如果超过了100w,直接跳出,然后输出无解就行了。

代码:

#include <bits/stdc++.h>
using namespace std;
struct dot
{
  int x,y,step;//一个点的信息
};
struct mag
{
  int x1,x2,y1,y2;//存储2个魔法阵相对应的下标
} mf[1000];
int vis[1001][1001],n,m,dx[4] = {-1,0,1,0},dy[4] = {0,-1,0,1};
char a[1001][1001];
queue<dot> q;
int main()
{
  cin>>n>>m;
  for(int i = 1; i <= n; i++)
    for(int j = 1; j <= m; j++)
    {
      cin>>a[i][j];
      if(i == 1 && j == 1)
      {
        q.push(dot {i,j,0});
        vis[i][j] = 1;
      }
      if(a[i][j] <= 'Z' && a[i][j] >= 'A')
        if(mf[a[i][j]].x1 == 0 && mf[a[i][j]].y1 == 0) mf[a[i][j]].x1 = i,mf[a[i][j]].y =  j;
        else mf[a[i][j]].x2 = i,mf[a[i][j]].y2 = j;
    }
  int py = 0;
  while(!q.empty())
  {
  	if(py > 1000001) break;
    dot t = q.front();
    q.pop();
    for(int i = 0; i < 4; i++)
    {
      dot t2 = t;
      t2.x += dx[i];
      t2.y += dy[i];
      t2.step += 1;
      if(t2.x > 0 && t2.y > 0 && t2.x <= n && t2.y <= m && a[t2.x][t2.y] != '1' && vis[t2.x][t2.y] == 0)
      {
        if(t2.x == n && t2.y == m)
        {
          cout<<t2.step;
          return 0;
        }
        else if(a[t2.x][t2.y] == '0')
        {
          q.push(t2);
          vis[t2.x][t2.y] = 1;
        }
        else if(a[t2.x][t2.y] >= 'A' && a[t2.x][t2.y] <= 'Z')
        {
          if(mf[a[t2.x][t2.y]].x1 == t2.x && mf[a[t2.x][t2.y]].y1 == t2.y) q.push(dot {mf[a[t2.x][t2.y]].x2,mf[a[t2.x][t2.y]].y2,t2.step});
          else if(mf[a[t2.x][t2.y]].x2 == t2.x && mf[a[t2.x][t2.y]].y2 == t2.y) q.push(dot {mf[a[t2.x][t2.y]].x1,mf[a[t2.x][t2.y]].y1,t2.step});
        }
      }
      /*for(int i = 1; i <= n; i++)
      {
        for(int j = 1; j <= m; j++)
          cout<<vis[i][j]<<" ";
        cout<<endl;
      }
      cout<<t.x<<" "<<t.y<<endl<<t2.x<<" "<<t2.y<<endl<<endl;*/
    }
    py++;
  }
  cout<<"No Solution.";
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值