HNU大一小学期作业三 棋盘

题目:

【问题描述】

        棋盘是指一个行和列编号从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

大概思路:

①输入的处理。将给定矩阵设为全局变量,用getchar()读入每一个元素。在输入正整数N后还要用个getchar()吃掉空格,在每一行的元素读取完后也要用个getchar()吃掉。

②图的遍历。以给定矩阵的每一个元素作为棋盘左上角的顶点进行深搜。

③结果的输出。将不同尺寸的棋盘的数目保存在数组里,输出尺寸的最大值和最大尺寸的数目。

AC代码:

#include<iostream>
#include<cstring>
using namespace std;
bool map[2001][2001];
int N,num[2001],ans=0;
void dfs(int m,int n,int depth)//以map[m][n]左上角的顶点,depth为尺寸的棋盘 
{
	if(map[m][n]==0) return ;//左上角的顶点为白色,返回
	if(m+depth-1>N||n+depth-1>N) return ;//行或列超过给定矩阵的范围,返回
	int i,j;
	for(i=1;i<=depth;i++)
	{
		for(j=1;j<=depth;j++)
		{    //行号和列号之和为偶数,该点却是白色,返回
			if((i+j)%2==0&&map[m+i-1][n+j-1]==0)
			return ;
			//行号和列号之和为偶数 ,该点却是嘿色,返回
			else if((i+j)%2==1&&map[m+i-1][n+j-1]==1)
			return ;
		}
	}
    //进行到这一步说明以map[m][n]左上角的顶点,depth为尺寸的棋盘是存在的
	if(depth>ans) ans=depth;//更新最大尺寸
	num[depth]++;//将该尺寸的数目加一
	dfs(m,n,++depth);//尺寸扩大一,仍以该点为左上角的顶点深搜
}
int main()
{
	int i,j;
	cin>>N;
    getchar();//吃掉空格
	memset(num,0,sizeof(num));//初始化为0
	for(i=1;i<=N;i++)
	{
		for(j=1;j<=N;j++)
		map[i][j]=getchar()-'0';
		getchar();//吃掉换行符
	}
	for(i=1;i<=N;i++)
	for(j=1;j<=N;j++)
	{
		dfs(i,j,1);//对给定矩阵中的每一个点进行深搜
	}
	cout<<ans<<' '<<num[ans];//输出结果
}

猜你喜欢

转载自blog.csdn.net/qq_40889820/article/details/81188459