搜索(BFS,DFS)Flood Fill算法

城堡问题

bfs求出连通块数量,以及统计出每块大小

每次要判断当前坐标下哪个方向没有墙

西北东南其实就是二进制向右移动0,1,2,3

#include <bits/stdc++.h>
#define ll long long
#define x first
#define y second
#define INF 0x7f7f7f7f

using namespace std;
typedef pair<ll,int> PII;

const int N=50+10;

int  n,m,ans;
int dx[4]= {0,-1,0,1};//注意向北走行数减1 
int dy[4]= {-1,0,1,0};
int vis[N][N];
int g[N][N];

int bfs(int x,int y) {
	queue<PII> q;
	q.push({x,y});
	vis[x][y]=1;
	int cnt=0;
	while(!q.empty()) {
		PII p=q.front();
		q.pop();
		cnt++;
		for(int i=0; i<4; i++) {//西北东南按这个方向枚举 
			int nx=p.x+dx[i];
			int ny=p.y+dy[i];
			if(nx<1||ny<1||nx>n||ny>m||vis[nx][ny])continue;
			if(!(g[p.x][p.y]>>i&1)){ //原来的位置在要移动的方向上没有墙阻挡
				q.push({nx,ny});
				vis[nx][ny]=1;
			}
		}

	}
	return cnt;
}


int main() {

	cin>>n>>m;

	for(int i=1; i<=n; i++) {
		for(int j=1; j<=m; j++) {
			cin>>g[i][j];
		}
	}
    int maxv=-INF; 
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=m; j++) {
			if(!vis[i][j]) {
				ans++;
				maxv=max(maxv,bfs(i,j)); //最大面积
			}
		}
	}
	cout<<ans<<endl;
	cout<<maxv<<endl;


	return 0;
}

山峰和山谷

在bfs时要把邻居也纳入进来检查判断

#include <bits/stdc++.h>
#define ll long long
#define x first
#define y second
#define INF 0x7f7f7f7f

using namespace std;
typedef pair<ll,int> PII;

const int N=1000+10;

int  n,m,ans;
int dx[8]= {1,0,-1,0,1,-1,-1,1};//注意向北走行数减1
int dy[8]= {0,1,0,-1,1,1,-1,-1};
int vis[N][N];
int g[N][N];

void bfs(int x,int y,bool &haslower,bool &hashigher) {
	queue<PII> q;
	q.push({x,y});
	vis[x][y]=1;
	while(!q.empty()) {
		PII p=q.front();
		q.pop();
		for(int i=0; i<8; i++) {
			int nx=p.x+dx[i];
			int ny=p.y+dy[i];
			if(nx<1||ny<1||nx>n||ny>n)continue;//不能写vis[nx][ny]因为他要对比邻居山的高度 
			if(g[nx][ny]!=g[p.x][p.y]) {
				if(g[nx][ny]>g[p.x][p.y])hashigher=true;
				else haslower=true;
			} else if(!vis[nx][ny]) {
				q.push({nx,ny});
				vis[nx][ny]=1;
			}
		}

	}
}


int main() {

	cin>>n;

	for(int i=1; i<=n; i++) {
		for(int j=1; j<=n; j++) {
			cin>>g[i][j];
		}
	}
	int low=0,high=0;;
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=n; j++) {
			if(!vis[i][j]) {
				bool haslower=false;
				bool hashigher=false;
				bfs(i,j,haslower,hashigher);
				//如果既有比他高的又有比他低的,那么他不作为山峰 
				if(!hashigher)high++;
				if(!haslower)low++;
			}
		}
	}
	cout<<high<<" "<<low<<endl;


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值