【29.70%】【codeforces 723D】Lakes in Berland
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard 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 n, m 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
5 4 1
..
*.
..**
output
1
..
..**
input
3 3 0
.
output
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.
【题解】
题意:和边相连的连通块不算lake,一开始有s个lake(s>=k),求最少要去掉多少个cell of lake才能让总的lake个数变为k;
先预处理将那些边上的连通块给置为1表示置为平地。但是要记录一下这些点的坐标。最后输出的时候还是要变回来。
然后i=1->n;j=1->m;寻找连通块。并记录各个连通块的起始坐标。获取这个连通块的cell个数设为size;
以size为关键字升序排序;
看需要减少多少个湖。就从小到大累加相应个数的size;
根据记录的起始坐标再次进行bfs(需要在一个初始且去掉边上的连通块的a数组的copy数组cpa进行);
最后把一开始去掉的边上的连通块重新置为是cell of lake;
最后输出整个矩阵;
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXN = 55;
const int dx[5] = { 0,1,-1,0,0 };
const int dy[5] = { 0,0,0,1,-1 };
int n, m,k,total = 0;
bool a[MAXN][MAXN] = { 0 }, cpa[MAXN][MAXN] = { 0 };
char s[MAXN];
struct data2
{
int x,y;
int size;
};
queue < data2 > dl;
vector < pair<int, int> > rest;
data2 qidian[MAXN*MAXN];
int cnt = 0;
void bfs1(int a0, int b0)
{
rest.push_back(make_pair(a0, b0));
a[a0][b0] = false;
data2 temp;
temp.x = a0, temp.y = b0;
dl.push(temp);
while (!dl.empty())
{
data2 temp1;
temp1 = dl.front();
int a1 = temp1.x, b1 = temp1.y;
dl.pop();
for (int i = 1; i <= 4; i++)
{
int a2 = a1 + dx[i];
int b2 = b1 + dy[i];
if (a[a2][b2])
{
a[a2][b2] = false;
rest.push_back(make_pair(a2, b2));
data2 temp2;
temp2.x = a2;
temp2.y = b2;
dl.push(temp2);
}
}
}
}
int bfs2(int a0, int b0,bool a[MAXN][MAXN])
{
int num = 1;
a[a0][b0] = false;
data2 temp;
temp.x = a0, temp.y = b0;
dl.push(temp);
while (!dl.empty())
{
data2 temp1;
temp1 = dl.front();
int a1 = temp1.x, b1 = temp1.y;
dl.pop();
for (int i = 1; i <= 4; i++)
{
int a2 = a1 + dx[i];
int b2 = b1 + dy[i];
if (a[a2][b2])
{
a[a2][b2] = false;
num++;
data2 temp2;
temp2.x = a2;
temp2.y = b2;
dl.push(temp2);
}
}
}
return num;
}
bool cmp(data2 a, data2 b)
{
return a.size < b.size;
}
int main()
{
//freopen("F:\\rush.txt", "r", stdin);
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i <= n; i++)
{
scanf("%s", s);
for (int j = 1; j <= m; j++)
if (s[j - 1] == '.')
a[i][j] = 1;
else
a[i][j] = 0;
}
for (int i = 1; i <= m; i++)//去掉边上的连通块。并记录那些连通块的每个cell的坐标之后方便回溯
if (a[1][i])
bfs1(1, i);
for (int i = 1; i <= m; i++)
if (a[n][i])
bfs1(n, i);
for (int i = 1; i <= n; i++)
if (a[i][1])
bfs1(i, 1);
for (int i = 1; i <= n; i++)
if (a[i][m])
bfs1(i, m);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)//copy一下a数组
cpa[i][j] = a[i][j];//这个cpa数组用来最后输出答案。删除操作也在这上面进行
for (int i = 1;i <= n;i++)
for (int j = 1; j <= m; j++)
if (a[i][j])
{
cnt++;
qidian[cnt].x = i; qidian[cnt].y = j;//记录这个湖的起点坐标
qidian[cnt].size = bfs2(i, j,a);
}
total = cnt - k;
sort(qidian + 1, qidian + 1 + cnt, cmp);//以湖的大小为关键字升序排
int i = 0,zs = 0;
while (total > 0)//看需要去掉几个湖
{
i++;
zs += qidian[i].size;
bfs2(qidian[i].x, qidian[i].y, cpa);
total--;
}
int len = rest.size();
for (int i = 0; i <= len - 1; i++)//把之前置为平地的重新置为cell of lake
{
int x = rest[i].first, y = rest[i].second;
cpa[x][y] = 1;
}
printf("%d\n", zs);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
if (cpa[i][j] == 1)
putchar('.');
else
putchar('*');
printf("\n");
}
return 0;
}
【29.70%】【codeforces 723D】Lakes in Berland的更多相关文章
- codeforces 723D: Lakes in Berland
Description The map of Berland is a rectangle of the size n × m, which consists of cells of size 1 × ...
- 【Codeforces 723D】Lakes in Berland (dfs)
海洋包围的小岛,岛内的有湖,'.'代表水,'*'代表陆地,给出的n*m的地图里至少有k个湖,求填掉面积尽量少的水,使得湖的数量正好为k. dfs找出所有水联通块,判断一下是否是湖(海水区非湖).将湖按 ...
- 【 BowWow and the Timetable CodeForces - 1204A 】【思维】
题目链接 可以发现 十进制4 对应 二进制100 十进制16 对应 二进制10000 十进制64 对应 二进制1000000 可以发现每多两个零,4的次幂就增加1. 用string读入题目给定的二进制 ...
- 【35.29%】【codeforces 557C】Arthur and Table
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 【55.70%】【codeforces 557A】Ilya and Diplomas
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 【39.29%】【codeforces 552E】Vanya and Brackets
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 【29.89%】【codeforces 734D】Anton and Chess
time limit per test4 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【22.70%】【codeforces 591C】 Median Smoothing
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【codeforces 29B】Traffic Lights
[题目链接]:http://codeforces.com/problemset/problem/29/B [题意] 一辆车; 让从A开到B; 然后速度是v; (只有在信号灯前面才能停下来..否则其他时 ...
随机推荐
- FileChannel的深入理解
一,官方描写叙述 一个读,写,映射,操作文件的通道. 文件通道有能够被查询和改动的一个当前位置.文件本身包括了一个可悲读写的变长字节序列,而且它的当前的size会被查询.当被写入的字节超过当前文件的大 ...
- UML中的用例图
用例图构成:參与者(actor).用例(use case).子系统(subsystem) 关联(Association) 泛化(Inheritance) 就是通常理解的继承关系,子用例和父用例类似,但 ...
- lighttpd启动不了,libssl.so.4&libcrypto.so.4 缺失
lighttd的出错日志在 log/out_lighttpd 里,当lighttd启动不了时候,这里文件中会说明原因. 今天的报错是 error while loading shared librar ...
- 例说linux内核与应用数据通信(四):映射设备内核空间到用户态
[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet.文章仅供学习交流,请勿用于商业用途] 一个进程的内存映象由以下几部分组成:代码段.数据段.BSS段和 ...
- 矩阵乘法java代码实现
矩阵只有当左边矩阵的列数等于右边矩阵的行数时,它们才可以相乘, 乘积矩阵的行数等于左边矩阵的行数,乘积矩阵的列数等于右边矩阵的列数 即A矩阵m*n,B矩阵n*p,C矩阵m*p: package exa ...
- 嵌入式 Linux应用程序如何读取(修改)芯片寄存器的值
这一问题来自项目中一个实际的需求:我需要在Linux启动之后,确认我指定的芯片寄存器是否与我在uboot的配置一致. 举个例子:寄存器地址:0x20000010负责对DDR2的时序配置,该寄存器是在u ...
- windows程序生成目标平台与CLR运行执行过程
C# 编译器提供一个选项, 该选项允许指定最终生成的程序集只能运行在32位windows版本的X86机器上使用, 只能在运行64位windows的X64机器上使用, 或者只能在32为windows R ...
- D3.js中对array的使用
由于D3类库和array密切相关,我们有必要讨论一下D3中的数据绑定以及在数组内部运算的方法. 1.D3中的数组 和其他编程语言一样,D3的数组元素可以是数字或者字符等类型,例如: someData= ...
- ubuntu-安装中文拼音输入法
一下内容转载自http://blog.chinaunix.net/uid-24410388-id-3501873.html 自己验证了可用.转载了,已留做日后使用 步骤: step1:安装ibus所需 ...
- Spark SQL概念学习系列之DataFrame与RDD的区别
不多说,直接上干货! DataFrame的推出,让Spark具备了处理大规模结构化数据的能力,不仅比原有的RDD转化方式更加简单易用,而且获得了更高的计算性能.Spark能够轻松实现从MySQL到Da ...