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. 解决:target overrides the `GCC_PREPROCESSOR_DEFINITIONS`

    [!] Please close any current Xcode sessions and use `******.xcworkspace` for this project from now o ...

  2. Mac环境下执行npm install报权限错误解决办法

    1. 一般情况 sudo npm install 注:这相当于windows系统中的 以管理员身份执行,加上sudo后会要求你输入苹果账号密码,而且在输入的时候是没有字符提示的,密码输入完直接按回车就 ...

  3. MQ脚本回放报错2059

    1.响应2059错误 1.1.   涉及协议 MQ,调试回放阶段 1.2.   错误信息 完成码2原因为2059:未能为 '10.200.100.75:QMEMBFE' 创建 MQQueueManag ...

  4. 如何使用终端默认情况下阻止Mac应用保存到iCloud

    当您保存要在Mac上的Pages,Numbers,TextEdit或其他基于云的应用程序中处理的文档时,该保存的默认位置是iCloud.尽管这对某些人或某些文档来说可能是一件好事,但您可能会厌倦每次更 ...

  5. C#添加错误日志信息

    错误日志是软件用来记录运行时出错信息的文本文件.编程人员和维护人员等可以利用错误日志对系统进行调试和维护. 系统日志 系统日志包含了由Windows系统组件记录的事件.例如,在启动期间装入驱动程序或其 ...

  6. ETCD:HTTP JSON API通过gRPC网关

    原文地址:HTTP JSON API through the gRPC gateway etcd v3 使用 gRPC 作为消息协议.etcd项目包括一个基于gRPC的Go客户端和一个命令行工具,et ...

  7. PalletOne调色板跨链的ETH提币实现

    实现区块链的跨链,最主要的诉求就是Token的转移,而Token的跨链转移又分为充币和提币2种操作.以PalletOne调色板来说,如果要把ETH跨链到PalletOne上来流转,就是ETH的充币操作 ...

  8. ABAP - AT END OF 的使用

    TYPES: begin of ty_tab , num() type i, str() type c, end of ty_tab. data: gw_tab TYPE ty_tab , gt_ta ...

  9. ASP.NET MVC5基础-控制器(Controller)详解

    在上文ASP.NET MVC5基础 – MVC文件架构中我们简单了解了下控制器Controller的作用,本文我将详细介绍控制器Controller的使用方法. Controller的运行过程 上文我 ...

  10. abp去掉AbpUser中的Name,Surname,去掉姓和名分离

    abp是国外的框架,默认的框架中的AbpUser表中的Name和Surname是分开的,这不符合国情:可以先去掉 1. 在User类中重写Name和Surname,并设置为私有 2. 在DbConte ...