E. Arson In Berland Forest

The Berland Forest can be represented as an infinite cell plane. Every cell contains a tree. That is, contained before the recent events.

A destructive fire raged through the Forest, and several trees were damaged by it. Precisely speaking, you have a n×m rectangle map which represents the damaged part of the Forest. The damaged trees were marked as "X" while the remaining ones were marked as ".". You are sure that all burnt trees are shown on the map. All the trees outside the map are undamaged.

The firemen quickly extinguished the fire, and now they are investigating the cause of it. The main version is that there was an arson: at some moment of time (let's consider it as 0) some trees were set on fire. At the beginning of minute 0, only the trees that were set on fire initially were burning. At the end of each minute, the fire spread from every burning tree to each of 8 neighboring trees. At the beginning of minute T, the fire was extinguished.

The firemen want to find the arsonists as quickly as possible. The problem is, they know neither the value of T (how long the fire has been raging) nor the coordinates of the trees that were initially set on fire. They want you to find the maximum value of T (to know how far could the arsonists escape) and a possible set of trees that could be initially set on fire.

Note that you'd like to maximize value T but the set of trees can be arbitrary.

Input

The first line contains two integer n and m (1≤n,m≤106, 1≤n⋅m≤106) — the sizes of the map.

Next n lines contain the map. The i-th line corresponds to the i-th row of the map and contains m-character string. The j-th character of the i-th string is "X" if the corresponding tree is burnt and "." otherwise.

It's guaranteed that the map contains at least one "X".

Output

In the first line print the single integer T — the maximum time the Forest was on fire. In the next n lines print the certificate: the map (n×m rectangle) where the trees that were set on fire are marked as "X" and all other trees are marked as ".".

Examples

input

3 6

XXXXXX

XXXXXX

XXXXXX

output

1

......

.X.XX.

......

input

10 10

.XXXXXX...

.XXXXXX...

.XXXXXX...

.XXXXXX...

.XXXXXXXX.

...XXXXXX.

...XXXXXX.

...XXXXXX.

...XXXXXX.

..........

output

2

..........

..........

...XX.....

..........

..........

..........

.....XX...

..........

..........

..........

input

4 5

X....

..XXX

..XXX

..XXX

output

0

X....

..XXX

..XXX

..XXX

题意

现在有个地方发生了火灾,火焰每秒都会往上下左右对角线八个方向进行蔓延。

现在给你最终的火焰图,你想使得燃烧的时间最长,问你最开始的火焰是什么样的。

题解

最暴力的做法是我把当前没燃烧的点加进队列里面,然后每秒用bfs去模拟熄灭的过程。

那么什么时候不能熄灭了呢,就是我熄灭后再蔓延不能得到之前的样子的时候,就是不能再熄灭了。

暴力会T,所以我们得改成二分。

二分+bfs其实也会T,会被卡常数,所以最好改成前缀和的。前缀和的话,火焰从中间向八个方向燃烧,改成向三个方向燃烧的前缀和做法。

具体看代码。

代码

#include<bits/stdc++.h>
using namespace std; int main() {
ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int N, M; cin >> N >> M;
vector<string> G(N);
for (int i = 0; i < N; i++) {
cin >> G[i];
} vector<vector<int>> maxSquare(N, vector<int>(M));
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (G[i][j] == '.') maxSquare[i][j] = 0;
else if (i == 0 || j == 0) {
maxSquare[i][j] = 1;
} else {
maxSquare[i][j] = 1 + min(maxSquare[i-1][j-1], min(maxSquare[i-1][j], maxSquare[i][j-1]));
}
}
}
vector<vector<int>> coverDist(N, vector<int>(M));
int mi = 0;
int ma = int(2e6);
while (ma - mi > 1) {
int md = (mi + ma) / 2;
int s = 2 * md + 1;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (maxSquare[i][j] >= s) {
coverDist[i][j] = s;
} else {
coverDist[i][j] = 0;
}
}
}
for (int i = N-1; i >= 0; i--) {
for (int j = M-1; j >= 0; j--) {
if (i > 0) {
coverDist[i-1][j] = max(coverDist[i-1][j], coverDist[i][j] - 1);
}
if (j > 0) {
coverDist[i][j-1] = max(coverDist[i][j-1], coverDist[i][j] - 1);
}
if (i > 0 && j > 0) {
coverDist[i-1][j-1] = max(coverDist[i-1][j-1], coverDist[i][j] - 1);
}
}
}
bool isGood = true;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (G[i][j] == '.') continue;
if (coverDist[i][j] == 0) isGood = false;
}
}
if (isGood) {
mi = md;
} else {
ma = md;
}
} cout << mi << '\n';
int s = 2 * mi + 1;
vector<string> ans(N, string(M, '.'));
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (maxSquare[i][j] >= s) {
ans[i - mi][j - mi] = 'X';
}
}
}
for (int i = 0; i < N; i++) {
cout << ans[i] << '\n';
} return 0;
}

Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) E. Arson In Berland Forest 二分 前缀和的更多相关文章

  1. Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3

    A,有多个线段,求一条最短的线段长度,能过覆盖到所又线段,例如(2,4)和(5,6) 那么我们需要4 5连起来,长度为1,例如(2,10)(3,11),用(3,10) 思路:我们想一下如果题目说的是最 ...

  2. Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) F2. Wrong Answer on test 233 (Hard Version) dp 数学

    F2. Wrong Answer on test 233 (Hard Version) Your program fails again. This time it gets "Wrong ...

  3. Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) D2. Optimal Subsequences (Hard Version) 数据结构 贪心

    D2. Optimal Subsequences (Hard Version) This is the harder version of the problem. In this version, ...

  4. Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) C. Messy 构造

    C. Messy You are fed up with your messy room, so you decided to clean it up. Your room is a bracket ...

  5. Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) B. Box 贪心

    B. Box Permutation p is a sequence of integers p=[p1,p2,-,pn], consisting of n distinct (unique) pos ...

  6. Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) A. Math Problem 水题

    A. Math Problem Your math teacher gave you the following problem: There are n segments on the x-axis ...

  7. Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) C Messy

    //因为可以反转n次 所以可以得到任何可以构成的序列 #include<iostream> #include<string> #include<vector> us ...

  8. Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) B Box

    #include<bits/stdc++.h> using namespace std; ]; ]; int main() { int total; cin>>total; w ...

  9. Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) A Math Problem

    //只要从所有区间右端点的最小值覆盖到所有区间左端点的最大值即可 #include<iostream> using namespace std ; int x,y; int n; int ...

随机推荐

  1. JDK新特性关于流操作部分

    // array 工具类 可以用来快捷的将数组转化为list List<String> strings = Arrays.asList("zhongguo", &quo ...

  2. Owhat sign参数分析

    需求:Owath进行商品购买时,psot提交的参数,有个sign,分析生成的算法. 1)点击商品购买后,进行抓包. 2)搜索sign定位赋值函数,OWAPIParamsDict paramsDictW ...

  3. How do I unmute my Lenovo laptop?

    If the FN key does have a green light just press and hold down the FN button on the bottom left of t ...

  4. s3c2440裸机-代码重定位(2.编程实现代码重定位)

    代码重定位(2.编程实现代码重定位) 1.引入链接脚本 我们上一节讲述了为什么要重定位代码,那么怎么去重定位代码呢? 上一节我们发现"arm-linux-ld -Ttext 0 -Tdata ...

  5. August 18th, 2019. Week 34th, Sunday

    Fear doesn't shut you down, it wakes you up. 恐惧不会消磨你的意志,它能激发你的潜能. We all know that fear is powerful, ...

  6. 关于eclipse的maven项目Java Build Path中maven依赖报错问题

    场景描述: respository仓库位置变动过,代码注解等报错 解决方法: 选中项目,点击maven ->update Project即可.

  7. leetcode-字符串篇

    Implement strStr() /** * Implement strStr(). *  * Return the index of the first occurrence of needle ...

  8. Quartz.NET总结(三)如配置jobs

    前两篇文章,已经介绍了Quartz.NET的使用和Cron表达式表达式的写法,今天说一说Quartz的配置,Quartz相关的配置有三个quartz.config.quartz_jobs.xml.lo ...

  9. SpringCloud的入门学习之概念理解、Config配置中心

    1.SpringCloud Config分布式配置中心.分布式系统面临的配置问题. 答:微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务.由于每个 ...

  10. ubuntu安装gcc不同的版本

    服务器ubuntu14.04安装ns3.29中,显示gcc版本过低 使用apt-get安装失败,ubuntu14.04默认安装gcc4.8.4,无法下载更高级的gcc版本 先找到资料1,脚本尝试了,下 ...