湖大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);	//尺寸扩大一,仍以该该点为左上角深搜 
} 
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
SDUT-OJ(Software Development University of Tsinghua Online Judge)是一个在线编程平台,提供给清华大学软件学院的学生和爱好者练习和解决算法问题的环境,其中包括各种计算机科学题目,包括数据结构、算法、图形等。对于"最小生成树"(Minimum Spanning Tree, MST)问题,它是图论中的经典问题,目标是从一个加权无向图中找到一棵包含所有顶点的树,使得树的所有边的权重之和最小。 在C语言中,最常见的是使用Prim算法或Kruskal算法来求解最小生成树。Prim算法从一个顶点开始,逐步添加与当前生成树相连且权重最小的边,直到所有顶点都被包含;而Kruskal算法则是从小到大对所有边排序,每次选取没有形成环的新边加入到树中。 如果你想了解如何用C语言实现这些算法,这里简单概括一下: - 通常使用优先队列(堆)来存储边和它们的权重,以便快速查找最小值。 - 从任意一个顶点开始,遍历与其相邻的边,若新边不形成环,就更新树,并将新边加入优先队列。 - Kruskal算法: - 先将所有的边按照权重升序排序。 - 创建一个空的最小生成树,然后依次取出排序后的边,如果这条边连接的两个顶点不在同一个连通分量,则将其添加到树中。 如果你需要更详细的代码示例,或者有具体的问题想了解(比如如何处理环、如何实现优先队列等),请告诉我,我会为你提供相应的帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

steven_moyu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值