给定一个 n×n 的二维数组,数组中的每个元素都是 02。请你统计数组中连续的四个元素恰好组成 2020 的序列个数。
连续序列的方向限定为以下 4 种

  1. 水平向右:同一行中,从左到右连续 4 个元素
  2. 竖直向下:同一列中,从上到下连续 4 个元素
  3. 主对角线向下:左上到右下方向,连续 4 个元素
  4. 副对角线向下:右上到左下方向,连续 4 个元素

输入格式

  1. 第一行输入一个整数 n(4≤n≤1000),表示二维数组的行数和列数
  2. 接下来 n 行,每行输入一个长度为 n 的字符串,字符串仅由 02 组成

输出格式

输出一个整数,表示满足条件的 2020 序列的总个数

这道题目刚开始我理解的意思时,一个序列的四个元素只能用一次,下一次寻找的序列的元素要是没有被选中过的,这种想法应该有很多不一样的答案。
这道题的意思其实时找出所有可能不考虑是否构成序列的元素是否被用过。
我们只需要遍历每一个元素,看它在这四种序列方向上是否可以构成一个2020序列。在遍历时可以简化枚举次数。
比如一个n*n的二维数组,(i,j)处的数要构成横向的2020则必须要j+3<=n,同理要构成竖向的2020要满足i+3<=n,构成主对角线向下的2020则必须要满足i+3<=n&&j+3<=n,构成副对角线向下的2020则必须要满足i+3<=n&&j-3>=1

#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main()
{
int n,cnt=0;
cin>>n;
vector<vector<int>> arr(n+1, vector<int>(n+1));
for(int i=1;i<=n;i++)
{
string a;
cin>>a;
for(int j=1;j<=n;j++)
arr[i][j]=a[j-1]-'0';
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(j+3<=n&&arr[i][j]==2&&arr[i][j+1]==0&&arr[i][j+2]==2&&arr[i][j+3]==0)
cnt++;
if(i+3<=n&&arr[i][j]==2&&arr[i+1][j]==0&&arr[i+2][j]==2&&arr[i+3][j]==0)
cnt++;
if(i+3<=n&&j+3<=n&&arr[i][j]==2&&arr[i+1][j+1]==0&&arr[i+2][j+2]==2&&arr[i+3][j+3]==0)
cnt++;
if(j-3>=1&&i+3<=n&&arr[i][j]==2&&arr[i+1][j-1]==0&&arr[i+2][j-2]==2&&arr[i+3][j-3]==0)
cnt++;
}
}
cout<<cnt;
}