搜索--再填格子

 

 

 

题目描述

 

有一个由数字 0、1 组成的方阵中,存在一任意形状的封闭区域,封闭区域由数字1 包围构成,每个节点只能走上下左右 4 个方向。现要求只把【最大封闭区域】内的空间填写成2 。

例如: 6×6 的方阵:

6
0 1 0 0 0 0
1 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1

 

填写后如下:

 0 1 0 0 0 0
 1 0 1 1 1 1
 0 1 1 2 2 1
 1 1 2 2 2 1
 1 2 2 2 2 1
 1 1 1 1 1 1

输入要求

 

每组测试数据第一行一个整数 n(1≤n≤30)

接下来 n 行,由 0 和 1 组成的 n×n 的方阵。

封闭区域内至少有一个0,测试数据保证最大区域只有一个。

 

 

输出要求

 

已经填好数字 2 的完整方阵。(每个数字后面有一个空格!)

 

 

输入样例

6
0 1 0 0 0 0
1 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1

 

 

输出样例

0 1 0 0 0 0
1 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1

答案:深搜

#include<iostream>
#include<cstring>

using namespace std;
int a[40][40]; 
int n;
int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};  // 右 左 下 上 
int cnt = 0;  // 某一个封闭区域的大小 
int maxn = 0;  // 最大封闭区域大小
int id = 3;  // 染色区域的编号
int max_id = id;
 
 
void dfs(int x, int y)
{
	if(x<0 || x>n+1 || y<0 || y>n+1 || a[x][y]!=0)  //禁止染色的判断 x<0 || x>n+1 || y<0 || y>n+1为矩阵4个边
		return ;
	a[x][y] = id;  //染色
	cnt++;
	for(int i=0; i<4; i++){
		dfs(x+dir[i][0], y+dir[i][1]);
	} 
}


int main()
{
	cin >> n;
	memset(a, 0, sizeof(a)); 
	int i;
	// 输入数据 
	for( i=1; i<=n; i++)
		for(int j=1; j<=n; j++){
			int k;
			cin >> k;
			a[i][j] = k;
		}
		
	//将边缘的0和其连接块都染色
	dfs(0, 0);
	id++;
	
	for( i=2; i<n; i++)
		for(int j=2; j<n; j++){
			cnt = 0;
			// 搜索每一个元素,找到最大封闭区域 
			dfs(i, j);
			//cout << cnt;
			if(cnt > maxn){
				maxn = cnt;
				max_id = id;
			}
			id++;	
		}

		
// 输出	
for( i=1; i<=n; i++){
		for(int j=1; j<=n; j++){
			if(a[i][j] == 1)
				cout << a[i][j] << " ";
			else if(a[i][j] != max_id)
				cout << '0' << " ";
			else 
				cout << '2' << " ";

		}	
		cout << endl;
	
	}	

	return 0;
}

#include<iostream>
#include<cstring>

using namespace std;
int a[40][40]; 
int n;
int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};  // 右 左 下 上 
/*
-----------
  | 0 | 1
-----------
0 | 0 | 1
-----------
1 | 0 |-1
-----------
2 | 1 | 0
-----------
3 |-1 | 0
-----------
*/
int cnt = 0;  // 某一个封闭区域的大小 
int maxn = 0;  // 最大封闭区域大小
int id = 3;  // 染色区域的编号
int max_id = id;
 
void dfs(int x, int y){
	
	if(x<0 || x>n+1 || y<0 || y>n+1 || a[x][y]!=0) //碰到不为0的就会缩回去
		return ;
	a[x][y] = id;
	cnt++;
	for(int i=0; i<4; i++){
		dfs(x+dir[i][0], y+dir[i][1]);
	} 
}

int main()
{
	cin >> n;
	memset(a, 0, sizeof(a)); //全部置0
	int i;
	// 输入数据 ,外圈为0
	for( i=1; i<=n; i++)
		for(int j=1; j<=n; j++){
			int k;
			cin >> k;
			a[i][j] = k;
		}
		
	//将边缘的0和其连接块都染色
	dfs(0, 0);
	id++;
	
	for( i=2; i<n; i++)// 由于输入的矩阵最外圈不可能是封闭的
		for(int j=2; j<n; j++){
			cnt = 0;
			// 搜索每一个元素,找到最大封闭区域 
			dfs(i, j);
			//cout << cnt;
			if(cnt > maxn){
				maxn = cnt;
				max_id = id;
			}
			id++;	
		}

		
// 输出	
		cout<<endl;
		for( i=0; i<=n; i++){  //相当于现有矩阵往里缩2层开始
		for(int j=0; j<=n+1; j++){//一列一列的查询
			if(a[i][j]/10==0)
				cout <<" "<< a[i][j] << " ";
			else
				cout << a[i][j] << " ";

		}	
		cout << endl;
	
	}	

	return 0;
}

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

萌新待开发

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

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

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

打赏作者

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

抵扣说明:

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

余额充值