洛谷P1141(记忆化bfs)

6 篇文章 0 订阅
1 篇文章 0 订阅

题目描述

有一个仅由数字0与1组成的n×n格迷宫。若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上。

你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。

输入输出格式

输入格式:

输入的第1行为两个正整数n,m。

下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格。

接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移动到多少格。

出格式:

输出包括m行,对于每个询问输出相应答案。

思路:如果对每个点bfs肯定TLE,所以在每次bfs后,把这次bfs找到的联通块中的点记录下来,省去大量重复的搜索
见代码:
#include<bits/stdc++.h>
using namespace std;
int num=0;
int n,m;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
char mapp[1010][1010];
int rem[1010][1010];
int lian[1000010];
typedef struct
{
	int xx;
	int yy;
}  node;
node point[1000010];
bool out(int x,int y)
{
	if(x>=1&&x<=n&&y>=1&&y<=n)
	return false;
	else
	return true;
}
int bfs(int x,int y)
{
    int cnt=0;
	queue<node> q;
    node a;
    a.xx=x;
    a.yy=y;
    q.push(a);
    num++;
    cnt++;
    rem[x][y]=num;
   while(!q.empty())
  {
      node t=q.front();
	  q.pop();
	  	for(int i=0;i<4;i++)
	{
	    node tt;
		int temx=t.xx+dx[i];
	    int temy=t.yy+dy[i];
		if(!out(temx,temy)&&mapp[temx][temy]!=mapp[t.xx][t.yy]&&rem[temx][temy]==0)
		{
		    tt.xx=temx;
		    tt.yy=temy;
		    q.push(tt);
			rem[temx][temy]=num;
			cnt++;	
		}	
	}
  }
  lian[num]=cnt;
  return cnt;	
}
int main()
{
	int tx,ty;
	scanf("%d%d",&n,&m);
	getchar();
	for(int i=1;i<=n;i++)
	{	
		scanf("%s",(mapp[i]+1));
	}
	for(int k=1;k<=m;k++)
	{
		scanf("%d%d",&tx,&ty);
		if(rem[tx][ty]==0)
		printf("%d\n",bfs(tx,ty));
		else
		{
			printf("%d\n",lian[rem[tx][ty]]);
		}
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值