【题目链接】
【题目考点】
1. 二维数组
2. 方向数组
表示上下左右的方向数组:
int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
或
int dx[4] = {0,0,1,-1}, dy[4] = {1,-1,0,0};
【解题思路】
理解题意,相邻两个’#'算作一块草丛。
可以理解为:
.#.
是1个草丛
.##
是1个草丛
###
是2个草丛
.#.
###
是4个草丛
.#.
因而每个#
有两种情况:
- 参与到一个两个
#
组成的草丛中,相当于每个#
贡献0.5个草丛。如果它周围有x个#
,它就会参与构成x个草丛,它贡献的草丛数为 0.5 x 0.5x 0.5x - 单独形成一个草丛,每个
#
贡献1个草丛
为了避免处理小数,把上述推导中的小数变为整数,改为计分制,一个草丛算2分,叙述如下:
遍历整个二维数组,如果当前位置是#
,则遍历其周围上下左右四个位置
- 如果这四个位置中存在
#
,则中心位置参与构成两个#
的草丛。每存在一个#
,加1分。 - 如果四个位置不存在
#
,那么中心位置的#
独自构成一个草丛,加2分。
最后将总分数除以2,即为草丛的个数。
【题解代码】
解法1:二维方向数组
#include <bits/stdc++.h>
using namespace std;
#define N 105
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int main()
{//单独的草算2分,如果由2块组成的草一定会被计算两次,每个算1分。最后除以2。
char a[N][N];
int r, c, s = 0;
cin >> r >> c;
for(int i = 1; i <= r; i++)
for(int j = 1; j <= c; j++)
cin >> a[i][j];
for(int i = 1; i <= r; i++)
for(int j = 1; j <= c; j++)
{
if(a[i][j] == '#')
{
bool flag = false;//i,j周围有是否有草
for(int d = 0; d < 4; d++)
{
int x = i + dir[d][0], y = j + dir[d][1];
if(x >= 1 && x <= r && y >= 1 && y <= c && a[x][y] == '#')
{
s++;
flag = true;
}
}
if(flag == false)//一个#单独构成草丛
s += 2;
}
}
cout << s/2;
return 0;
}
解法2:一维方向数组
#include <bits/stdc++.h>
using namespace std;
#define N 105
int dx[4] = {0,0,1,-1}, dy[4] = {1,-1,0,0};
int main()
{
char a[N][N];
int r, c, s = 0;
cin >> r >> c;
for(int i = 1; i <= r; i++)
for(int j = 1; j <= c; j++)
cin >> a[i][j];
for(int i = 1; i <= r; i++)
for(int j = 1; j <= c; j++)
{
if(a[i][j] == '#')
{
bool flag = false;//i,j周围有没有草
for(int d = 0; d < 4; d++)
{
int x = i + dx[d], y = j + dy[d];
if(x >= 1 && x <= r && y >= 1 && y <= c && a[x][y] == '#')
{
s++;
flag = true;
}
}
if(flag == false)
s += 2;
}
}
cout << s/2;
return 0;
}