P1141 01迷宫 题解 DFSorBFS

9 篇文章 0 订阅

这道题虽然在BFS的练习范围
但是我看到这道题第一个念头是用dfs写
不过我自己写的dfs tle了
然后参(模)考(仿)了题解里的一个dfs思路终于过了
下面放上参考的思路博客地址:
思路参考博客

DFS代码:

#include<bits/stdc++.h>
using namespace std;
int n, m;
int dx[4]={0, -1, 0, 1}, dy[4]={-1, 0, 1, 0};
int a[1010][1010], vis[1010][1010], ans[1000000];

struct Node{
	int x, y, a, i;

	Node(int _x, int _y, int _a, int _i){	//构造函数 
		x= _x, y=_y, a=_a, i = _i;
	}
};


void dfs(Node t){
	if(vis[t.x][t.y] || t.x<=0 || t.x>n || t.y<=0 || t.y>n || a[t.x][t.y]!=t.a)	//剪枝 
		return;
	
	vis [t.x][t.y] = t.i;	//记录下每个位置哪一轮搜过, 如果前面搜过了后面就不用搜了 
	ans[t.i] ++;	//记录能到达的格子数 
	
	for(int i=0; i<4; i++){	//搜四个方向 
		int nx = t.x+dx[i], ny = t.y+dy[i];
		Node tmp(nx, ny, !t.a, t.i);
		dfs(tmp);
	}
}

int main(){
	int sx, sy;
	char c;
	cin>>n>>m;
	
	for(int i=1; i<=n; i++){
		for(int j=1; j<=n; j++){
			cin>>c;
			a[i][j] = c - '0';
		}
	}
	
	
	for(int i=1; i<=m; i++){
		cin>>sx>>sy;
		
		if(!vis[sx][sy]){	//若这个位置没搜过 
			Node node(sx, sy, a[sx][sy], i);
			dfs(node);
		}else{	//位置搜过了 
			ans[i] = ans[vis[sx][sy]];
		}
	}
	
	for(int i=1; i<=m; i++){
		cout<<ans[i]<<endl;
	}
	return 0;
}

以上面的思路用BFS也实现了一次

BFS代码:

#include<bits/stdc++.h>
using namespace std;
int n, m;
int dx[4]={0, -1, 0, 1}, dy[4]={-1, 0, 1, 0};
int a[1010][1010], vis[1010][1010], ans[1000000];

struct Node{
	int x, y, a, i;
	
	Node(){}	//这里空构造函数不要忘

	Node(int _x, int _y, int _a, int _i){	//构造函数 
		x= _x, y=_y, a=_a, i=_i;
	}
};
Node node[10000000];

void bfs(Node t){
	int head=0, tail=1;
	node[head] = t;
	vis[t.x][t.y] = t.i;	//记录哪一轮的搜索,前面搜过了后面就不需要搜了 
	int sum = 1;	//记录这一轮搜索能走的格子数 
	
	while(head<=tail){
		Node tmp = node[head];
		
		for(int i=0; i<4; i++){
			int nx=tmp.x+dx[i], ny=tmp.y+dy[i];
			
			if(vis[nx][ny] || nx<=0 || nx>n || ny<=0 || ny>n || a[nx][ny]!=tmp.a)
				continue;
			
			sum++;
			vis[nx][ny] = tmp.i;
			Node nxt(nx, ny, !tmp.a, tmp.i);
			node[tail++] = nxt;
		}
		
		head++;
	}
	ans[t.i] = sum;	
}

int main(){
	int sx, sy;
	char c;
	cin>>n>>m;
	
	for(int i=1; i<=n; i++){
		for(int j=1; j<=n; j++){
			cin>>c;
			a[i][j] = c - '0';
		}
	}
	
	int cnt = 1;
	for(int i=1; i<=n; i++){
		for(int j=1; j<=n; j++){
			if(!vis[i][j]){
				Node t(i, j, !a[i][j], cnt++);
				bfs(t);
			}
		}
	}
	
	for(int i=1; i<=m; i++){
		cin>>sx>>sy;
		cout<<ans[vis[sx][sy]]<<endl;	//直接输出每个位置对应的轮数的格子数 
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值