本文已参与[新人创作礼]活动,一起开启掘金创作之路
Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目描述
这是3月14日代码源div2的每日一题。
知识点:前缀和
网格判断 - 题目 - Daimayuan Online Judge
您将获得一个 n×n 的网格,网格中每个正方形的颜色为黑色或白色。如果满足以下所有条件,则网格是正确的:
- 每行的黑色方块数与白色方块数相同。
- 每列的黑色正方形数与白色方块数相同。
- 没有行或列具有 3 个以上相同颜色的连续正方形。
给定网格,确定它是否正确。
输入格式
第一行一个数字 n(2≤n≤24), 并且数字 n 是偶数。
接下来 n 行,每行包含一个长度为n的由字符B和W组成的字符串,代表网格正方形的颜色。
输出格式
如果网格正确,请打印数字 1 在一行上。否则,请打印数字 0 在一行上。
样例输入
4
WBBW
WBWB
BWWB
BWBW
样例输出
1
问题解析
这题可以直接计数做,我这里使用前缀和节省点细节操作。
先选一个要记录的颜色,我这里选择的是‘W’,然后遍历数组计算前缀和,遇到当前格子为‘W'时前缀和++。当遍历到的位置大于3时,我们就可以回头看之前的位置了,如果当前位置的前缀和减去往前数第三个位置的前缀和的差值等于3时,说明这中间连着的都是’W',不满足情况直接输出0。如果差值为0,说明这段路上都没有‘W',都是’B‘,这也是不符合条件的,输出0。
我们先一行行的遍历,如果没有异样,那我们就再一列列来。如果也没有问题那就输出1。
AC代码
list写法
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
int main()
{
int n;
cin >> n;
vector<int>s(n + 1);
vector<vector<char>>v(n + 1, vector<char>(n + 1));
string str;
for (int i = 1; i <= n; i++)
{
cin >> str;
for (int j = 1; j <= n; j++)
{
v[i][j] = str[j - 1];
s[j] = s[j - 1];
if (str[j - 1] == 'W')s[j] += 1;
if (j >= 4&&(s[j]==s[j-3]||s[j]-s[j-3]==3))
{
cout << 0 << endl;
return 0;
}
}
if (s[n] != n / 2)
{
cout << 0 << endl;
return 0;
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
s[j] = s[j - 1];
if (v[j][i] == 'W')s[j] += 1;
if (j >= 4 && (s[j] == s[j - 3] || s[j] - s[j - 3] == 3))
{
cout << 0 << endl;
return 0;
}
}
if (s[n] != n / 2)
{
cout << 0 << endl;
return 0;
}
}
cout << 1 << endl;
return 0;
}