It takes two (搜索)

文章描述了一个编程问题,涉及在二维网格中使用广度优先搜索(BFS)判断A字符是否能形成可构成矩形的区域。关键在于找到右下角坐标并比较搜索面积与矩形面积是否匹配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本题链接:登录—专业IT笔试面试备考平台_牛客网

题目:

样例:

输入
3 4
AAAO
AAAA
AAAA

输出
NO

思路:

        根据题目意思,如果存在的 A 联通不可以成为 矩形,输出 NO,否则输出 YES

        这道题看数据范围是 1000 的图,所以可以联想到搜索。

        对于 ‘ 感染类 ’ 的搜索,BFS最直观合适。

        其中一个核心点就是如何知道右下角的坐标。

        当搜索寻找矩形的时候,我们找到相应的右下角坐标,随后统计搜索的面积与右下角坐标和左上角坐标相乘的面积,是否一致,如果一致,则是矩形,反之。

        我们可以注意到,右下角的坐标永远比坐上角的坐标大,即  右下角(x,y) > 左上角(x,y)

        所以我们每次取 坐标的最大值即可。

        // 寻找右下角
		lx = max(lx,now.x);
		ly = max(ly,now.y);

代码详解如下:

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#define endl '\n'
#define x first
#define y second
#define int long long
#define YES puts("YES")
#define NO puts("NO")
#define umap unordered_map
#define All(x) x.begin(),x.end()
#pragma GCC optimize(3,"Ofast","inline")
#define IOS std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
const int N = 2e6 + 10;
inline void solve();
signed main()
{
//	freopen("a.txt", "r", stdin);
	IOS;
	int _t = 1;
// 	cin >> _t;
	while (_t--)
	{
		solve();
	}

	return 0;
}

bool st[1010][1010];
string g[N];
int n,m;
using PII = pair<int,int>;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

// 判断是否可进一步搜索
inline bool isRun(int x,int y)
{
	return (x >= 0 and x < n and y >= 0 and y < m and !st[x][y] and g[x][y] == 'A');
} 

// BFS 搜索
inline bool BFS(int x,int y)
{
	queue<PII>q;
	q.emplace(PII(x,y));
	
	int sum = 0; // 记录搜索面积
	
	int lx = -1,ly = -1;	// 记录右下角坐标
	
	while(q.size())
	{
		PII now = q.front();
		q.pop();
		++sum;	// 统计搜索到的面积
		
		// 寻找右下角
		lx = max(lx,now.x);
		ly = max(ly,now.y);
		
		st[now.x][now.y] = true;
		for(int i = 0;i < 4;++i)
		{
			int bx = now.x + dx[i];
			int by = now.y + dy[i];
			if(isRun(bx,by))
			{
				q.emplace(PII(bx,by));
				st[bx][by] = true;
			}
		}
	}
	
	// 计算右下角坐标和左上角坐标形成的矩形面积
	int t = (lx - x + 1)*(ly - y + 1);
	
	// 判断是否与搜索面积相等
	return (t != sum);
}

inline void solve()
{
	cin >> n >> m;
	for(int i = 0;i < n;++i) cin >> g[i];
	
	for(int i = 0;i < n;++i)
	{
		for(int j = 0;j < m;++j)
		{
			if(!st[i][j] and g[i][j] == 'A')
			{
				if(BFS(i,j))
				{
					cout << "NO" << endl;
					return ;
				}
			}
		}
	}
	cout << "YES" << endl;
}

最后提交:

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值