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. VC遍历访问目录下的文件

    访问目录文件夹下的文件是经常需要的操作,C/C++和win32接口都没有提供直接调用的函数.在这里总结了几个经常用到的函数,通过MFC的CFileFind函数递归遍历实现,包括以下几个功能函数: 查找 ...

  2. iOS中截取字符串指定位置

    直接上代码: NSString *string = @"今天是个好日子,忘记穿秋裤了"; NSString *string1 = [];//截取掉下标7之后的字符串 NSStrin ...

  3. 【模板】分治 FFT

    Link Solution 有两种解法. 法1: 直接上分治FFT,也就是CDQ分治+FFT. 具体做法是先递归左半边,算出左半边答案之后,将左半边贡献到右半边,然后递归右半边. 分治是一个log的, ...

  4. R-4 方差分析

    本节内容: 1:方差分析的原理 2:单因数方差分析 .双因数分析 3:交互项 一:方差分析是原理 方差分析原理 对总体均值的假设检验,有三种情况:1.总体均值与某个常数进行比较:2.两个总体均值之间的 ...

  5. Java之继承性

    为什么要有继承 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可.其中,多个类可以称为子类,单独那一个类称为父类.超类或者基类. 继 ...

  6. jvaa之初始化块

    1.初始化块的作用:对java对象进行初始化: 2.程序的执行顺序:声明成员变量的默认值-->显示初始化,多个初始化块依次被执行(同级别下按先后顺序执行)-->构造器在对成员进行赋值操作. ...

  7. Linux系统:centos7下搭建ZooKeeper3.4中间件,常用命令总结

    本文源码:GitHub·点这里 || GitEE·点这里 一.下载解压 1.Zookeeper简介 Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题,它能提供 ...

  8. Spring Cloud(一):入门篇

    Spring Cloud 简介 Spring Cloud 是一个基于 Spring Boot 实现的微服务架构开发工具,可以快速构建分布式系统中的某些常用模式,如配置管理.服务治理.断路器.智能路由. ...

  9. CAD简易口诀,保你一天就记住!零基础也能轻松学!CAD制图宝典!

    如何才能快速的学习CAD制图呢?不仅仅需要多练习,CAD口诀也是不能错过的哦!实用干货这一个就够了快点收藏起来! 1.创建直线的快捷方式是L+空格 2.创建圆的快捷方式是C+空格 3.创建圆弧的快捷方 ...

  10. PHPStudyLite启动不成功怎么办

    点击环境端口检测 有端口打开则关闭 一切正常后重新开启