暖炉与水豚-----2024睿抗RAICOM编程组(省赛)B题解析

在一个 N*M 的矩阵中有若干水豚以及暖炉,暖炉可以辐射以它自身为中心的 3×3 范围里的水豚,使其变得暖呼呼的。

谜题里存在一只冷的要命的水豚,你需要移动其中的一个暖炉,使所有水豚都变得暖呼呼的。

在往下读题前,如果你有兴趣的话,不妨思考一下如何解答这个谜题。(思考结果与题目无关,可跳过。)

这个谜题的关键在于,单纯从图中能看到的暖炉来说是无解的,但如果注意到,第 33 行第 66 列的水豚明明周围没有暖炉,却也处于暖呼呼的状态,就能推测出来图中的那个对话框挡住了一个暖炉,只要移动这个暖炉就可以完成题目的要求。

现在我们将谜题一般化,对于给定的一个 N×M 的矩阵、对应的所有水豚状态、以及能看到的暖炉摆放情况,已知最多只有一只水豚的状态不太对劲(周围没有暖炉却暖呼呼的),你需要推测有哪些格子可能藏了暖炉。

一个空格可能藏了暖炉可以理解为:当前空格设置暖炉后整个矩阵的状态会从不合法变为合法。

输入格式

输入第一行是两个正整数 N,M 表示矩阵的大小。

接下来的 N行,每行有 M个字符,第 i 行的第 j 个字符表示矩阵中对应位置的状态,其中:

数据范围

1≤N,M≤1000

  • . 表示空格(或者说,看上去是空格的格子);
  • c 表示很冷的水豚;
  • w 表示暖呼呼的水豚;
  • m 表示暖炉。
  • 输出格式
  • 输出若干行,每行两个正整数 r 和 c,表示第 r 行第 c 列有可能藏了一个暖炉,有多个可能时,先按 r 从小到大输出,r 相同时再按 c 从小到大输出。如果没有一个格子可能藏了暖炉, 则在一行中输出 Too cold!

    行与列均从 1 开始编号。

    注意:

  • 一个空格可能藏了暖炉可以理解为:当前空格设置暖炉后整个矩阵的状态会从不合法变为合法。(必须是不合法变为合法,不能是合法变为合法
  • Too cold! 有两种情况:1、不存在不对劲水豚(即整个矩阵的初始状态就是合法的)。2、存在不对劲水豚(即整个矩阵的初始状态就是不合法的),但不存在可能藏了暖炉的空格(无论如何给定矩阵都不可能合法)。
输入样例:
6 8
wm....mw
.w..ww..
..wm.wwm
w.w....w
.m.c.m..
w.....w.
输出样例:
2 7
3 5
4 6
4 7

本题的题干有些长,但要求的问题还是比较简单的

遍历每一只海豚,如果是w但四周没有m,就是有问题的格子

#include 
#include 
#include 
using namespace std;

const int N = 2010,M = N<<1;
int n,m;
char g[N][M];
vector> arr;

// 判断格子是否在地图内 
bool inmp(int x,int y)
{
	return x>=1&&x<=n&&y>=1&&y<=m;
}

// 对于要查找的字符,需要遍历其四周 
bool find(int x,int y,char c)
{
	for(int i=x-1;i<=x+1;i++)
	{
		for(int j=y-1;j<=y+1;j++)
		{
			if(inmp(i,j))
			{
				if(g[i][j]==c) return true;
			}
		}
	}
	return false;
}

int main(void)
{
	cin >> n >> m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin >> g[i][j];
		}
	}
	// 找到那一只反常的海豚,题目说只有一只 
	int x=0,y=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(g[i][j]=='c')
			{
				if(!find(i,j,'m'))
				{
					x=i,y=j;
				}
			}
		}
	}
	// 在反常的海豚四周寻找空地,有可能隐藏了炉子
	// 注意c的四周的空地要淘汰掉 
	for(int i=x-1;i<=x+1;i++)
	{
		for(int j=y-1;j<=y+1;j++)
		{
			if(inmp(i,j))
			{
				if(!find(i,j,'c')&&g[i][j]=='.')
				{
					arr.push_back({i,j});
				}
			}
		}
	}
	// 输出结果 
	if(x==0&&y==1||arr.size()==0) cout << "Too cold!" << endl;
	else for(auto &[x,y]:arr) cout << x << ' ' << y << endl;
	return 0;
}

感谢查看!

你可能感兴趣的:(acWing好题题解,算法)