【codeforces 732D】Lakes in Berland(DFS)

针对一个矩形地图,通过算法确定最小数量的水域转换为陆地,以保留指定数量的内陆湖泊。首先标记非内陆湖泊区域,使用深度优先搜索统计并排序内陆湖泊面积,选择面积最小的湖泊进行填充。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

D. Lakes in Berland

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

The map of Berland is a rectangle of the size n × m, which consists of cells of size 1 × 1. Each cell is either land or water. The map is surrounded by the ocean.

Lakes are the maximal regions of water cells, connected by sides, which are not connected with the ocean. Formally, lake is a set of water cells, such that it's possible to get from any cell of the set to any other without leaving the set and moving only to cells adjacent by the side, none of them is located on the border of the rectangle, and it's impossible to add one more water cell to the set such that it will be connected with any other cell.

You task is to fill up with the earth the minimum number of water cells so that there will be exactly k lakes in Berland. Note that the initial number of lakes on the map is not less than k.

Input

The first line of the input contains three integers nm and k (1 ≤ n, m ≤ 50, 0 ≤ k ≤ 50) — the sizes of the map and the number of lakes which should be left on the map.

The next n lines contain m characters each — the description of the map. Each of the characters is either '.' (it means that the corresponding cell is water) or '*' (it means that the corresponding cell is land).

It is guaranteed that the map contain at least k lakes.

Output

In the first line print the minimum number of cells which should be transformed from water to land.

In the next n lines print m symbols — the map after the changes. The format must strictly follow the format of the map in the input data (there is no need to print the size of the map). If there are several answers, print any of them.

It is guaranteed that the answer exists on the given data.

Examples

input

Copy

5 4 1
****
*..*
****
**.*
..**

output

Copy

1
****
*..*
****
****
..**

input

Copy

3 3 0
***
*.*
***

output

Copy

1
***
***
***

Note

In the first example there are only two lakes — the first consists of the cells (2, 2) and (2, 3), the second consists of the cell (4, 3). It is profitable to cover the second lake because it is smaller. Pay attention that the area of water in the lower left corner is not a lake because this area share a border with the ocean.

 

对于这道题,我们应该先把非内嵌湖给标记一下,然后DFS统计出内嵌湖的个数,假设有m个,那么我们需要填上m-k个湖

我们DFS求出各个内嵌湖的面积,排序,记录下标,然后直接再DFS一次填上即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1005;
char maze[maxn][maxn];
char maze2[maxn][maxn];
int n,m,k,t;
int ans1;
int ans2;
int ass;
int vis[maxn][maxn];
int vis2[maxn][maxn];
int vis3[maxn][maxn];
int vis4[maxn][maxn];//maze边缘联通 
int vis5[maxn][maxn];//maze2边缘联通 
int area[maxn][maxn];


struct point
{
	int x,y;
	int area;
} p[10000];

bool cmp(point a,point b)
{
	return a.area<b.area;
}
 
 
int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}};
void DFSmaze(int x,int y)
{
	if(vis4[x][y]) return ;
	vis4[x][y]=1;
	if(maze[x][y]=='.')
	vis4[x][y]=1;
	for(int i=0;i<4;i++)
	{
		int dx=x+dir[i][0];
		int dy=y+dir[i][1];
		if(dx>=0&&dx<n&&dy>=0&&dy<m&&maze[dx][dy]=='.'&&!vis4[dx][dy])
		{
			DFSmaze(dx,dy);
		}
	}
}

void DFSmaze2(int x,int y)
{
	if(vis5[x][y]) return ;
	vis5[x][y]=1;
	if(maze2[x][y]=='.')
	vis5[x][y]=1;
	for(int i=0;i<4;i++)
	{
		int dx=x+dir[i][0];
		int dy=y+dir[i][1];
		if(dx>=0&&dx<n&&dy>=0&&dy<m&&maze2[dx][dy]=='.'&&!vis5[dx][dy])
		{
			DFSmaze2(dx,dy);
		}
	}
}
void DFS(int x,int y)
{
	if(vis[x][y]) return ;
	vis[x][y]=1;
	if(maze[x][y]=='.')
	maze[x][y]='*';
	for(int i=0;i<4;i++)
	{
		int dx=x+dir[i][0];
		int dy=y+dir[i][1];
		if(dx>=0&&dx<n&&dy>=0&&dy<m&&maze[dx][dy]=='.'&&!vis[dx][dy])
		{
			DFS(dx,dy);
		}
	}
}
void DFS3(int x,int y)//求出面积 
{
	if(vis3[x][y]) return ;
	vis3[x][y]=1;
	if(maze2[x][y]=='.')
	ass++;
	for(int i=0;i<4;i++)
	{
		int dx=x+dir[i][0];
		int dy=y+dir[i][1];
		if(dx>=0&&dx<n&&dy>=1&&dy<m&&maze2[dx][dy]=='.'&&!vis3[dx][dy])
		{
			DFS3(dx,dy);
		}
	}
}
void DFS2(int x,int y)
{
	if(vis2[x][y]) return ;
	vis2[x][y]=1;
	if(maze2[x][y]=='.')
	maze2[x][y]='*';
	for(int i=0;i<4;i++)
	{
		int dx=x+dir[i][0];
		int dy=y+dir[i][1];
		if(dx>=0&&dx<n&&dy>=0&&dy<m&&maze2[dx][dy]=='.'&&!vis2[dx][dy])
		{
			DFS2(dx,dy);
		}
	}
}
int main()
{
	ios::sync_with_stdio(0);
	while(cin>>n>>m>>k)
	{
		memset(vis,0,sizeof(vis));
		memset(vis2,0,sizeof(vis2));
		memset(vis3,0,sizeof(vis3));
		memset(area,0,sizeof(area));
		memset(vis4,0,sizeof(vis4));
		memset(vis5,0,sizeof(vis5));
		ans1=0;
		ans2=0;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				cin>>maze[i][j];
				maze2[i][j]=maze[i][j];
			}
		}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if((i==0||i==n-1||j==0||j==m-1)&&maze[i][j]=='.')
				{
					DFSmaze(i,j);
				}
			}
		}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if((i==0||i==n-1||j==0||j==m-1)&&maze2[i][j]=='.')
				{
					DFSmaze2(i,j);
				}
			}
		}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(maze[i][j]=='.'&&!vis4[i][j])
				{
					DFS(i,j);
					ans1++;
				}
			}
		}
//		cout<<ans1<<endl;
		t=ans1-k;
		int flag=0;
		int res=0;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(maze2[i][j]=='.'&&!vis5[i][j])
				{
					 ass=0;
					DFS3(i,j);
					area[i][j]=ass;
				}
			}
		}
		int cnt=0;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(area[i][j]>0)
				{
					p[cnt].x=i;
					p[cnt].y=j;
					p[cnt++].area=area[i][j];
				}
			}
		}
		sort(p,p+cnt,cmp);
		for(int i=0;i<t;i++)
		{
			res+=p[i].area;
		}
		for(int i=0;i<t;i++)
		{
			DFS2(p[i].x,p[i].y);
		}
		cout<<res<<endl;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				cout<<maze2[i][j];
			}
			cout<<endl;
		}
	}
	return 0;
}

 

### Codeforces Problem 1014D 解答与解释 当前问题并未提供关于 **Codeforces Problem 1014D** 的具体描述或相关背景信息。然而,基于常见的竞赛编程问题模式以及可能涉及的主题领域(如数据结构、算法优化等),可以推测该问题可能属于以下类别之一: #### 可能的解法方向 如果假设此问题是典型的计算几何或者图论类题目,则通常会涉及到如下知识点: - 图遍历(DFS 或 BFS) - 贪心策略的应用 - 动态规划的状态转移方程设计 由于未给出具体的输入输出样例和约束条件,这里无法直接针对Problem 1014D 提供精确解答。但是可以根据一般性的解决思路来探讨潜在的方法。 对于类似的复杂度较高的题目,在实现过程中需要注意边界情况处理得当,并且要充分考虑时间效率的要求[^5]。 以下是伪代码框架的一个简单例子用于说明如何构建解决方案逻辑流程: ```python def solve_problem(input_data): n, m = map(int, input().split()) # 初始化必要的变量或数组 graph = [[] for _ in range(n)] # 构建邻接表或其他形式的数据表示方法 for i in range(m): u, v = map(int, input().split()) graph[u].append(v) result = [] # 执行核心算法部分 (比如 DFS/BFS 遍历) visited = [False]*n def dfs(node): if not visited[node]: visited[node] = True for neighbor in graph[node]: dfs(neighbor) result.append(node) for node in range(n): dfs(node) return reversed(result) ``` 上述代码仅为示意用途,实际应用需依据具体题目调整细节参数设置及其功能模块定义[^6]。 #### 关键点总结 - 明确理解题意至关重要,尤其是关注特殊测试用例的设计意图。 - 对于大规模数据集操作时应优先选用高效的时间空间性能表现良好的技术手段。 - 结合实例验证理论推导过程中的每一步骤是否合理有效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值