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. jsp + js + 前端弹出框

    在项目中,前端页面我们时常需要各种各样的弹出框: 1.alert对话框:显示含有给定消息的"JavaScript Alert"对话框 代码: var a = "Hello ...

  2. RunLoop 和 autoreleasepool

    RunLoop 和 autoreleasepool RunLoop和线程的一一对应的,对应的方式是以key-value的方式保存在一个全局字典中 主线程的RunLoop会在初始化全局字典时创建 子线程 ...

  3. Bug 28450914 : ORA-600: [KDLRCI_GET_INLINE_DATA] SELECTING FROM CDB_FEATURE_USAGE_STATISTICS

    alert日志报错: 2019-11-18T07:15:12.704938+08:00Errors in file /u01/app/oracle/diag/rdbms/sibcyb1/SIBCYB1 ...

  4. alluxio 信息索引

    最近要使用到 alluxio,发现网上还是有一些文档很是不错,现在通过这篇文章进行索引一下,进行备忘: https://edgedef.com/2017/08/17/alluxio-%E5%B0%8F ...

  5. appium---模拟点击事件

    在做自动化的过程中都会遇到一些无法定位到的地方,或者通过元素怎么都定位不成功的地方,这个时候我们可以使用必杀技,通过坐标定位.具体的怎么操作呢? swipe点击事件 前面安静写过一篇关于swipe的滑 ...

  6. 用iText5-1-生成PDF

    参考代码和图片出处 https://howtodoinjava.com/library/read-generate-pdf-java-itext/ pom引入jar包 <dependencies ...

  7. C++ std::vector 基本用法2

    #include <iostream> #include <vector> using namespace std; int main() { int ar[10] = { 1 ...

  8. 深入浅出14个Java并发容器

    前言 不考虑多线程并发的情况下,容器类一般使用ArrayList.HashMap等线程不安全的类,效率更高.在并发场景下,常会用到ConcurrentHashMap.ArrayBlockingQueu ...

  9. ETCD:运行时重新配置设计

    原文地址:the runtime configuration design 运行时重新配置是分布式系统中最难,最容易出错的部分,尤其是在基于共识(像etcd)的系统中. 阅读并学习关于etcd的运行时 ...

  10. SpringBoot2.0 基础案例(17):自定义启动页,项目打包和指定运行环境

    本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.打包简介 springboot的打包方式有很多种.可以打war ...