bfs模板题

河南农业大学oj–天琴座的高雅
题目描述
给你一个地图,地图被分为nn的网格,每个格子都有一个高度w,并且每个格子与其上下左右,左上,左下,右上,右下八个方向的格子都是相邻的.
如果一片相邻的区域,这个区域所有格子高度相同,并且周围格子都比这片区域低,则为凸起。反之则为凹陷。现在想请你找到这个地图中凸起和凹陷的数量。如果所有格子都有相同的高度,那么整个地图即是凸起,又是凹陷。
输入
输入的第一行包含一个正整数n,表示地图的大小(1<=n<=1000)。接下来一个n
n的矩阵,表示地图上每个格子的高
度。(0<=w<=1e9)
输出
输出两个用空格隔开的整数 ,表示凸起和凹陷的数量。
样例输入 Copy

5
3 3 3 2 2
2 2 3 3 2
2 2 2 2 2
2 3 3 2 3
2 3 3 3 3

样例输出 Copy

2 1

代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 1e3 + 100;
int dir[8][2] = { 1, 0, 1, 1, 0, 1, -1, 1, -1, 0, -1, -1, 0, -1, 1, -1 };
int a[N][N], n;
bool vis[N][N];
int s1, s2;

int BFS(int x, int y) {
	queue <pair <int, int>> q;
	q.push({ x, y });
	vis[x][y] = true;

	bool ok1 = false, ok2 = false;
	while (!q.empty()) {
		pair <int, int> now = q.front();
		q.pop();
		int nx = now.first, ny = now.second;
		for (int i = 0; i < 8; i++) {
			int xx = nx + dir[i][0];
			int yy = ny + dir[i][1];
			if (xx < 1 || xx > n || yy < 1 || yy > n)
				continue;
			if (a[xx][yy] == a[nx][ny] && !vis[xx][yy]) {
				vis[xx][yy] = true;
				q.push({ xx, yy });
			}
			if (a[xx][yy] > a[nx][ny])
				ok1 = true;
			else if (a[xx][yy] < a[nx][ny])
				ok2 = true;
		}
	}
	if (ok1 && !ok2)
		return 1;
	else if (!ok1 && ok2)
		return -1;
	else
		return 0;
}

int main()
{
	set <int> st;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			scanf("%d", &a[i][j]);
			st.insert(a[i][j]);
		}
	}
	if (st.size() == 1)
		puts("1 1"), exit(0);

	int ans[2] = { 0, 0 };
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			if (vis[i][j])
				continue;
			int now = BFS(i, j);
			if (now > 0)
				ans[0]++;
			else if (now < 0)
				ans[1]++;
		}
	}
	printf("%d %d\n", ans[1], ans[0]);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

容艾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值