[计蒜客(蓝桥杯省赛)]蒜头君回家 原创

题目来源 计蒜客程序设计竞赛基础课(蓝桥杯省赛)

算法标签 宽度优先搜索

题目描述

在这里插入图片描述

提示

在这里插入图片描述

题目思路

首先
我先的是我找到一个钥匙,然后我就搜索家在哪里,我就OK了
但显然我做错了,因为地图上我走过的部分标记了,实际上在我拿到钥匙的时候我就需要地图B

所以
现在的思路是,我们找到钥匙,路线就从找钥匙切换为找家,地图从标记变为清零(切换到地图B)。
此时我们直接找家,当我们有钥匙(找加路线),且到家了,我们就可以返回结果。

if found key	
then
tmp.flag=1; turn to map[][][2]

if found home and flag=1
then
return distance 

注意

蓝桥杯只能使用C98
所以我们需要结构体强转,而不能使用构造函数列表初始化赋值

题目代码

#include<iostream>
#include<queue>
#include<cstring>

using namespace std;

typedef pair<int,int>PII;

const int N=4000;
char g[N][N];
bool st[N][N][2];

//struct node{//C11列表初始化
//	int x,y,s,f;
//	node(int xx,int yy,int ss,int ff){x = xx,y = yy,s = ss,f = ff;}
//};

struct node{int x,y,s,f;}; //x y横纵坐标,s距离,f标记 0招钥匙 1找家
//Node node=(Node){1,2,3,4};//C98强转
int n,m;

int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};//偏移量

int bfs(int x,int y)
{
  st[x][y][0]=1;//初始化
  queue<node>q;
  q.push((node){x,y,0,0});//放入头 C98强转
  //q.push(node(tx,ty,t.s+1,t.f));	C11
  
  while(q.size())
  {
    node t=q.front();
    q.pop();

    if(g[t.x][t.y]=='T'&&t.f==1)return t.s;//找到家
    if(g[t.x][t.y]=='P')t.f=1;//找到钥匙 此时开始找家 标记为找家路线 同时切换到地图2 相当于清空走动记录
    
    for(int i=0;i<4;i++)
    {
      int tx=dir[i][0]+t.x,ty=dir[i][1]+t.y;//临时偏移地点
      if(tx<0||tx>=n||ty<0||ty>=m)continue;//边界
      if(g[tx][ty]=='#')continue;//墙
      if(st[tx][ty][t.f])continue;//走过

      st[tx][ty][t.f]=1;//标记走过
      q.push((node){tx,ty,t.s+1,t.f});//距离+1 放入队列
    }
  }
}
int main()
{
  cin>>n>>m;
  
  for(int i=0;i<n;i++)cin>>g[i];
  
  int x,y;
  for(int i=0;i<n;i++)
  	for(int j=0;j<m;j++)
    	if(g[i][j]=='S')x=i,y=j;
      cout<<bfs(x,y);
  return 0;
}
posted @ 2021-07-10 20:54  俺叫西西弗斯  阅读(0)  评论(0)    收藏  举报  来源