dfs 填涂颜色

早⑧

今天莫名五点醒了,不过肯定是继续睡。
然后来上早⑧,无语的是,电脑没电了然后教室还没插座
我根本不想用机房的LJ电脑,但是无奈需要学习,勉强用这个做个算法题目

题目

题目链接

代码

这道题目其实很好哇
首先,如何判断是墙是一个难点。我一直想的是怎么做一个flag然后标明这个是墙的附近,然后又怎么知道哪些点属于墙的内部的呢。这也太难了额
那么就换一种思路,这么想,既然难以确定墙内的点,那就确定墙外的点吧。这样思路就很明确了,直接从开头dfs,遇到墙就退回去找别的口。但是这样做又会遇到问题就是开头的点就是1或者
|0| 1 | 1
|1| 0 | 1
| 1| 1| 0
这样的话刚开始就走不通了,就不会走到右下角的0,那么右下角的这个0也会被当做被围起来的输出
不过我们可以直接从(0,0)遍历(对图的要求是图是从(1,1)开始的)
然后图的范围要扩大到【0,n+1】,这样才能确保遍历的完整性

  • 6
    0 0 1 1 1 0
    1 1 1 0 1 0
    1 0 0 0 0 1
    1 1 0 1 1 1
    0 1 0 1 0 0
    0 1 1 1 0 0

比如这个数据,一开始我设置xx>=0&&xx<=n这样的话,就会导致右下角的2*2方块遍历不到,就会被认为是围起来的,实际上围起来他们的是隐形的墙(数组范围),这样就会导致出错
因此要记住写的是xx>=0&&xx<=n+1
dfs题目的细节确实很多,要仔细抠

还有如果不用从(0,0)开始,而是想着遍历整个图,遍历所有的起点,这是无法进行的吧,因为你要遍历所有的,就会不可避免地遍历到墙内的元素,将他们呢作为起点,这显然是不对的。

/*
填涂颜色
	
看了题解:
	 dfs搜索,把那一圈看作是围墙,从开始搜索,在地图的范围内搜索
	 如果遇到围墙就退回去,这样的话,只有四周全部是围墙的那些点才不会被搜索到 
*/


#include<iostream>

using namespace std;

const int N=40;
int g[N][N],path[N][N];//path用于判断某个点是否走过 
int n;
int dx[4]={0,0,-1,1},dy[4]={1,-1,0,0};


void dfs(int x,int y){
	path[x][y]=1;//表示走过了 
	for(int i=0;i<4;i++){
		int xx=x+dx[i],yy=y+dy[i];
		if(xx>=0&&xx<=n+1&&yy>=0&yy<=n+1&&path[xx][yy]==0&&g[xx][yy]==0){
			dfs(xx,yy);
		}
	}
}


int main(){
	cin>>n;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			cin>>g[i][j];
	dfs(0,0);//我们从(0,0)开始搜索是防止一开始就是墙 
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(path[i][j]==1)
				cout<<"0 ";
			if(path[i][j]==0&&g[i][j]==1)
				cout<<"1 ";
			if(path[i][j]==0&&g[i][j]==0)
				cout<<"2 ";
		}
		cout<<endl;
	}
	return 0;
} 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值