开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第23天,点击查看活动详情
顽皮恶魔
链接:ac.nowcoder.com/acm/problem…
来源:牛客网
题目描述
浮云阴,骤雨倾,顽皮恶魔镰刀显。
你的庄园是一块 n×m 的草坪。
现在有一些格子是普通植物 P,有一些格子是萝卜保护伞 *,有一些格子是僵尸 Z。(已经在格子上的僵尸不会吃掉植物或移动)
tip:萝卜保护伞可以保护周围 3×33\times33×3 的植物,即一个位于位置 (x,y)(x,y)(x,y) 的萝卜保护伞可以保护位于 (x±1,y),(x,y±1),(x±1,y±1) 以及自身九个格子上的植物。
现在你想知道,对于这样一块给定的草坪,假设有无穷多个飞贼,能够偷走最多数量的植物是多少。
输入描述:
全文第一行输入一个正整数 T(1≤T≤105),表示数据组数。
每组数据第一行输入两个正整数 n,m(1≤n,m≤103),表示草坪的长和宽。
接下来输入一个 n×m 的字符矩阵表示草坪的大小,字符矩阵中仅包含 Z、P、 * 三种字符。
数据保证 ∑n×m≤2×106 。
输出描述:
每行输出一个整数表示最多被偷走的植物数量。
示例1
输入
1
5 5
ZPZPZ
P*PZP
ZPZPZ
PZPZP
ZP*PZ
输出
5
说明
分别位于 (2,2) 和 (5,3) 上的保护伞可以保护周围的植物,最后能被偷走的植物如下图所示:(# 表示即将被偷走,∗ 表示保护伞,P 表示被保护)
思路
其实这个题简单来说,就是要找没有保护伞的植物,直接暴力搜索,如果找到普通植物就遍历他的身边有没有保护伞,这里我加了一个处理,不在搜索的时候就计数,搜索的时候如果遇到了保护伞,就把他能保护得范围都变成僵尸,最后直接重新遍历找P的个数就行。
代码
#include<bits/stdc++.h>
using namespace std;
char a[10010][10010];
void fun()
{
int n,m;
cin>>n>>m;
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>a[i][j];
//if(a[i][j]=='P'){ans++;}
}
//cout<<ans<<endl;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
//if(a[i][j]=='P'){ans++;}
if(a[i][j]=='*')
{
if(a[i-1][j-1]!='*') a[i-1][j-1]='Z';
if(a[i-1][j]!='*') a[i-1][j]='Z';
if(a[i-1][j+1]!='*') a[i-1][j+1]='Z';
if(a[i][j-1]!='*') a[i][j-1]='Z';
if(a[i][j+1]!='*') a[i][j+1]='Z';
if(a[i+1][j-1]!='*') a[i+1][j-1]='Z';
if(a[i+1][j]!='*') a[i+1][j]='Z';
if(a[i+1][j+1]!='*') a[i+1][j+1]='Z';
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(a[i][j]=='P') ans++;
}
cout<<ans<<endl;
}
int main()
{
int t;
cin>>t;
while(t--){
fun();
}
return 0;
}