洛谷—题解 P1141 01迷宫

原题链接P1141 01迷宫
有条件的小伙伴可以点进原网站开题,也可直接看我下面的截图。怎样都可,你们自己选 (๑•̀ㅂ•́)و✧
在这里插入图片描述在这里插入图片描述

题解一 BFS+连通块(๑•̀ㅂ•́)و✧
 这道题直接BFS会TLE四个点,很明显数据非常大,读一遍查一遍,太慢了!生活嘛,就需要多观察,多尝试。
 Attention:所有连在一起的格子答案都是一样的。所以先用bfs找出所有连通块,连通块内所有格子的答案就是连通块内格子的数目。
 思路:
 1、从输入的开始点搜,不用以每个点为起点全部都搜一遍,耗时且不必要。
 2、记录搜过的点
 3、连通块格子数开始为1,因为题中表示算自身点

代码

#include <iostream>
#include <stdlib.h>
#include <math.h>
#include <cstdio>
#include <cstring>

using namespace std;

struct note
{
	int x; //横坐标
	int y; //纵坐标
};
	
struct note que[10000001];
char a[10001][10001];
long long book[10001][10001]={0};
long long block[1000001][2],ans[10001][10001];	

//定义一个用于表示走的方向的数组
int next_[4][2]={{0,1},//向右走
				{1,0},//向下走
				{0,-1},//向左走
				{-1,0}};//向上走
int head,tail;
long long n,m;
long long startx,starty,tx,ty;
long long sum; 

//bfs block
void bfs(int x,int y)
{
	head =1;
	tail =1;
	que[tail].x=x;
	que[tail].y=y;
	tail++;

	while(head<tail)
	{
		for(int k = 0; k < 4; k++)
		{
			tx=que[head].x+ next_[k][0];
			ty=que[head].y+ next_[k][1];

			if (tx<1 || tx>n || ty<1 || ty>n)
				continue;
			if((a[tx][ty] != a[que[head].x][que[head].y]) && book[tx][ty]==0)
			{
				book[tx][ty]=1;
				que[tail].x=tx;
				que[tail].y=ty;
				tail++;
				sum++;
				block[sum][0]=tx;
				block[sum][1]=ty;
			}
		}
		head++;
	}


}

int main(int argc, char const *argv[])
{
	//input block
	scanf("%lld %lld",&n,&m);
	for (int i = 1; i <= n; ++i)
	{
		for (int j = 1; j <= n ; ++j)
		{
			cin>>a[i][j];
		}
	}

	//key block
	for (int i = 0; i < m; ++i)
	{
		scanf("%lld %lld",&startx,&starty);
		if(!book[startx][starty])
		{
			book[startx][starty]=1;
			sum=1;
			block[sum][0]=startx;
			block[sum][1]=starty;
			bfs(startx,starty);
			for(int k=1; k<=sum ; k++) 
				ans[block[k][0]][block[k][1]]=sum;
		}
		printf("%lld\n",ans[startx][starty]);
	}

	return 0;
}



题解二 DFS+连通块(๑•̀ㅂ•́)و✧
 具体思路和bfs差不多,只是用dfs去找所有的连通块。dfs的代码简直简单到我不敢信!o(*≧▽≦)ツ┏━┓
代码

#include <iostream>
#include <stdlib.h>
#include <math.h>
#include <cstdio>
#include <cstring>

using namespace std;
	
char a[10001][10001];
long long book[10001][10001]={0};
long long block[1000001][2],ans[10001][10001];	

//定义一个用于表示走的方向的数组
int next_[4][2]={{0,1},//向右走
				{1,0},//向下走
				{0,-1},//向左走
				{-1,0}};//向上走
long long n,m;
long long startx,starty,tx,ty;
long long sum; //the number of 

//dfs block
void dfs(int x,int y)
{
	sum++;
	block[sum][0]=x;
	block[sum][1]=y;
	for (int k = 0; k < 4; ++k)
	{
		tx=x+next_[k][0];
		ty=y+next_[k][1];

		if(tx<1 || tx>n || ty<1 || ty>n)
			continue;
		if((a[tx][ty]!=a[x][y])&&book[tx][ty]==0)
		{
			book[tx][ty]=1;
			dfs(tx,ty);
		}
	}
}

int main(int argc, char const *argv[])
{
	//input block
	scanf("%lld %lld",&n,&m);
	for (int i = 1; i <= n; ++i)
	{
		for (int j = 1; j <= n ; ++j)
		{
			cin>>a[i][j];
		}
	}

	//key block
	for (int i = 0; i < m; ++i)
	{
		scanf("%lld %lld",&startx,&starty);
		if(!book[startx][starty])
		{
			book[startx][starty]=1;
			sum=0;
			dfs(startx,starty);
			for(int k=1; k<=sum ; k++) 
				ans[block[k][0]][block[k][1]]=sum;
		}
		printf("%lld\n",ans[startx][starty]);
	}

	return 0;
}

祝福各位小伙伴们学的开心,学的快乐,早早的成为大牛。
曲终未必人散,有缘自会相逢
我是Mario,一个立志要考进MIT的程序猿。




[^注]:以上内容仅是个人观点,如涉及版权等问题,请联系我第一时间内删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值