湖大OJ----棋盘

问题描述:

棋盘是指一个行和列编号从1~N的NxN的二进制矩阵,当行号和列号之和为偶数时该矩阵对应位置为黑色的(1),否则为白色的(0)。以下图示为N=1、2、3时的棋盘。
这里写图片描述
给出一个NxN的二进制矩阵,请找出位于该矩阵内的最大尺寸的完整棋盘,以及最大尺寸棋盘的数量(棋盘可以交叠)。

输入形式:

每个测试用例的第一行是一个正整数N(1<=N<=2000),表示給定矩阵的行数和列数,接下来的N行描述了这个矩阵:每行有N个字符,既可以是“1”(代表黑块),也可以是“0”(代表白块)。矩阵至少包含一个“1”字符。

输出形式:

输出最大尺寸棋盘的行列的大小,以及最大棋盘的个数,以空格分隔。

样例输入:

5
00101
11010
00101
01010
11101

样例输出:

3 3

思路分析:

  1. 首先定义全局变量,输入对应个数的字符串。
  2. 将字符串转化为数组
  3. 对数组中的每个元素进行搜索,将不同大小的棋盘数目存放在数组中
  4. 输出结果

代码示例:

#include <iostream>
#include <string> 
using namespace std;
void string_to_int(string str,int k);
void dfs(int m,int n,int depth);
int a[2001][2001];
int num[2001],ans=0,N;
int main(){
    cin>>N;
    string str[N];
    for(int i=0;i<N;i++){
        cin>>str[i];
        string_to_int(str[i],i);
    }
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++){
            dfs(i,j,1);
        }
    }
    cout<<ans<<" "<<num[ans]<<endl;
}
//将字符串转化为数组 
void string_to_int(string str,int k){
    int len=str.length();
    for(int i=0;i<len;i++){
        if(str[i]=='1'){
            a[k+1][i+1]=1;
        }else {
            a[k+1][i+1]=0;
        }
    }
}
//搜索函数 
void dfs(int m,int n,int depth){    //以a[m][n]左上角为顶点,depth为尺寸的棋盘 
    if(a[m][n]==0){     //左上角的顶点为白色,返回 
        return ;
    } 
    if(m+depth-1>N||n+depth-1>N){   //行或列超过给定矩阵的范围,返回 
        return ;    
    } 
    for(int i=1;i<=depth;i++){
        for(int j=1;j<=depth;j++){
            //行号与列号之和为偶数 ,该点却是白色,返回 
            if((i+j)%2==0&&a[m+i-1][n+j-1]==0){
                return ;
            }else if((i+j)%2==1&&a[m+i-1][n+j-1]==1){
                //行号与列号之和为奇数,该点却是黑色,返回 
                return ;
            }
        }
    }
    //进行到这一步说明以a[m][n]左上角为顶点,depth为尺寸的棋盘是存在的 
    if(depth>ans){
        ans=depth;  //更新最大尺寸 
    }
    num[depth]++;   //将该尺寸的数目加一 
    dfs(m,n,++depth);   //尺寸扩大一,仍以该该点为左上角深搜 
} 

猜你喜欢

转载自blog.csdn.net/A_D_I_D_A_S/article/details/82469925