SP12880题解

更好的阅读体验

看到此题没有题解,我来水一发。

题意

(此题题意很重要,我就是看错题意调试了 7 天的)
a a a b b b 列( 3 ≤ a , b ≤ 250 3 \leq a,b \leq250 3a,b250)的矩阵中:

  • 字符 . 表示空白字段。

  • 字符 # 表示一个围栏。

  • 字符 k 代表绵羊。

  • 字符 v 代表狼。

狼和羊存活的规则为:

  1. 如果一片区域中羊比狼多,全部狼会死掉,否则全部羊会死掉。

  2. 如果一个地方可以不通过围栏走出矩阵,该地区羊和狼都会存活

思路

显而易见,本题目主要由两部分组成:通过围栏走出矩阵的部分以及其他部分。

首先对于 i = 1 i = 1 i=1 j = 1 j = 1 j=1 (即在边界),先打上标记。

再对于每一个未打上标记的地方,依次 BFS 算出每个地区存活的狼和羊的数量(同时将地区内的点打上标记),最后输出即可。

代码

#include<bits/stdc++.h>
#define x1 x.front()
#define y1 y.front()
using namespace std;
int main() {
	int a,b;
	scanf("%d%d",&a,&b);
	int kk,l = 0;
	char c[255][255];//存图
	bool d[255][255];//将图转化为bool形式
	for(int i = 1;i <= a;i++) {
		for(int j = 1;j <= b;j++) {
			d[i][j] = 1;
			cin>>c[i][j];
			if(c[i][j] == 'k') kk++;
			if(c[i][j] == 'v') l++;
			if(c[i][j] == '#') d[i][j] = 0;
		}
	}
    //BFS将能直接逃出去的打上标记
	for(int i = 1;i <= a;i++) {
		for(int j = 1;j <= b;j++) {
			if((i == 1 or j == 1) and d[i][j]) {
				queue<int>x,y;
				x.push(i),y.push(j);
				while(!x.empty()) {
					if(d[x1 + 1][y1] and x1 + 1 <= a) {
						d[x1 + 1][y1] = 0;
						x.push(x1 + 1),y.push(y1);
					}
					if(d[x1 - 1][y1] and x1 - 1 >= 1) {
						d[x1 - 1][y1] = 0;
						x.push(x1 - 1),y.push(y1);
					}
					if(d[x1][y1 + 1] and y1 + 1 <= b) {
						d[x1][y1 + 1] = 0;
						x.push(x1),y.push(y1 + 1);
					}
					if(d[x1][y1 - 1] and y1 - 1 >= 1) {
						d[x1][y1 - 1] = 0;
						x.push(x1),y.push(y1 - 1);
					}
					x.pop(),y.pop();
				}
			}
		}
	} 
	//BFS
	for(int i = 1;i <= a;i++) {
		for(int j = 1;j <= b;j++) {
			if(d[i][j]) {
				d[i][j] = 0;
				int e = 0,f = 0;
				queue<int>x,y;
				x.push(i),y.push(j);
				while(!x.empty()) {
					if(c[x1][y1] == 'k') e++;
					if(c[x1][y1] == 'v') f++;
					if(d[x1 + 1][y1] and x1 + 1 <= a) {
						d[x1 + 1][y1] = 0;
						x.push(x1 + 1),y.push(y1);
					}
					if(d[x1 - 1][y1] and x1 - 1 >= 1) {
						d[x1 - 1][y1] = 0;
						x.push(x1 - 1),y.push(y1);
					}
					if(d[x1][y1 + 1] and y1 + 1 <= b) {
						d[x1][y1 + 1] = 0;
						x.push(x1),y.push(y1 + 1);
					}
					if(d[x1][y1 - 1] and y1 - 1 >= 1) {
						d[x1][y1 - 1] = 0;
						x.push(x1),y.push(y1 - 1);
					}
					x.pop(),y.pop();
				}
				//进行判断
				if(e > f) l -= f;
				else kk -= e;
			}
		}
	}
    //输出
	printf("%d %d\n",kk,l);
}

附上一组调试数据:

7 7
#kvk##.
#####k#
#kvk#k#
#####v#
#vkv#v#
#####.#
kvkv###
6 7

Update

2022/12/21 更新题解中不完善的地方

2024/02/04 补充题解中思路部分

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值