中国电子学会历年真题-寻找边缘

题目描述:

给定一张 R*C 的地图,由 "X" 和 "O" 组成。

现在需要重新处理这张地图,找到地图边缘的那些 "O"。你需要将这些地图边缘上的 "O" 保留下来,然后将其他的 "O" 全部替换为 "X"。

地图边缘的 "O" 指的是那些处于第一行/列或最后一行/列上的 "O",以及从这些 "O" 的相邻位置(上下左右)延伸出去的 "O"。

时间限制:1000

内存限制:65536

输入

第一行是一个正整数 T,表示一共有 T 组数据。 对于每组数据,其第一行是两个正整数 R 和 C,表示地图的大小,用一个空格分开。 接下来的 R 行,每行包含了 C 个字符,分别是 "X" 或 "O"。 其中,0 < T <= 10,0 < R, C <= 500。

输出

对于每组数据,输出 R 行,每行包含了 C 个字符,分别是 "X" 或 "O"。 每组数据之间需要额外输出一个空行。

样例输入

2

2 3

OXX

XXO

5 5

XXXOX

XXXOX

XOOXX

XXOXX

XOXXX

样例输出

OXX

XXO

XXXOX

XXXOX

XXXXX

XXXXX

XOXXX

我的想法

这道题我用的是广搜

输入时先把每个'O'的位置存好(oxy),因为题目要求只留下第一行/列或最后一行/列上的 "O",和从这些 "O" 的相邻位置(上下左右)延伸出去的 "O",所以我们找到第一行/列或最后一行/列上的 "O",并往四周拓展就行了。

代码

#include <bits/stdc++.h>
using namespace std;
#define MAXN 505
struct node
{
	int x, y;
} oxy[MAXN];
int n, m, t, num, k;
char mp[MAXN][MAXN];
char ans[MAXN][MAXN];
bool v[MAXN][MAXN];
queue<node> q;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
void bfs()
{
	t = 0;
	ans[oxy[0].x][oxy[0].y] = 'O';
	v[oxy[0].x][oxy[0].y] = true;
	q.push(oxy[0]);
	while (q.size())
	{
		node tmp = q.front();
		q.pop();
//		if (tmp.x != 0 && tmp.x != n - 1 && tmp.y != 0 && tmp.y != n - 1)
//		{
//			t++;
//			if (t < num)
//				q.push(oxy[t]);
//			continue;
//		}
		//寻找当前点位附近可以去的地方
		for (int i = 0 ; i < 4 ; i++)
		{
			int tx = tmp.x + dx[i], ty = tmp.y + dy[i];
//			cout << tx << " " << ty << " " << !v[tx][ty] << " " << mp[tx][ty] << "\n";
			if (tx >= 0 && tx < n && ty >= 0 && ty < m && !v[tx][ty] && mp[tx][ty] == 'O')
			{
				ans[tx][ty] = 'O';
				v[tx][ty] = true;
				q.push(node{tx, ty});
			}
		}
		//开辟下一个点位
		if (q.size() == 0 && t + 1 < num)
		{
//			cout << q.size() << "\n";
			for (; ;)
			{
				t++;
				if (t < num && (oxy[t].x == 0 || oxy[t].x == n - 1 || oxy[t].y == 0 || oxy[t].y == m - 1))
				{
					q.push(oxy[t]);
					ans[oxy[t].x][oxy[t].y] = 'O';
					break;
				}
			}
		}
	}
}
int main()
{
	cin >> k;
	while (k--)
	{
		cin >> n >> m;
		num = 0;
		for (int i = 0 ; i < n ; i++)
		{
			for (int j = 0 ; j < m ; j++)
			{
				cin >> mp[i][j];
				ans[i][j] = 'X';
				if (mp[i][j] == 'O')
				{
					oxy[num].x = i;
					oxy[num].y = j;
//					cout << oxy[num].x << " " << oxy[num].y << " " << num << "\n";
					num++;
				}
			}
		}
//		cout<<num<<"\n";
		memset(v, false, sizeof(v));
		while (q.size())
			q.pop();
		bfs();
		for (int i = 0 ; i < n ; i++)
		{
			for (int j = 0 ; j < m ; j++)
			{
				cout << ans[i][j];
			}
			cout << "\n";
		}
	}
	return 0;
}

我也是第一次写博客,有什么不对的大佬请指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值