代码源:551、网格判断

163 阅读2分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路 logo.png

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目描述

这是3月14日代码源div2的每日一题。

知识点:前缀和

网格判断 - 题目 - Daimayuan Online Judge

您将获得一个 n×n 的网格,网格中每个正方形的颜色为黑色或白色。如果满足以下所有条件,则网格是正确的:

  • 每行的黑色方块数与白色方块数相同。
  • 每列的黑色正方形数与白色方块数相同。
  • 没有行或列具有 3 个以上相同颜色的连续正方形。

给定网格,确定它是否正确。

输入格式

第一行一个数字 n(2≤n≤24), 并且数字 n 是偶数。

接下来 n 行,每行包含一个长度为n的由字符BW组成的字符串,代表网格正方形的颜色。

输出格式

如果网格正确,请打印数字 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;
}