Problem:
B: Hokkaido University Hard

注意

　問題設定は A 問題と同一のものですが、制約のみが異なりますのでご注意ください。

物語

　北海道大学に合格し、新たな生活の始まりに心を躍らせるほむらちゃん。しかし彼女の前には、とてつもなく広いキャンパスが待ち受けていた...。

　「え...次の授業に間に合わないんだけど...」

問題

　北海道大学札幌キャンパスは異常に広いことで有名です。札幌キャンパスは縦に H マス、横に W マス並んだ長方形のマス目で表現されます。北から i マス、西から j マス進んだマスを (i,j) で表すことにします。キャンパス内にはいくつか建物があり、マス (i,j) で表される位置に建物がある場合は 'B' 、ない場合は '.' が c_{i,j} に書かれています。

　北海道大学の新入生のほむらちゃんは、キャンパスのあまりの広さに驚愕し、建物間の移動が心配になってきました。そこで、建物のある 2 つのマスのうち、最も遠い組はどれくらい離れているのかが気になりました。ここで、2 つのマスの組 (i,j) , (i',j') の間の距離を |i-i'|+|j-j'| と定義します。

　ほむらちゃんは、自分にはこの問題は難しいと思い、同級生のあなたに助けを求めてきました。ほむらちゃんの代わりに答えを求めてください。

入力形式

H W
c_{11}c_{12} ... c_{1W}
:
c_{H1}c_{H2} ... c_{HW}

制約

2 \leq H,W \leq 10^3

H,W は整数

c_{i,j} は 'B' か '.' のいずれかである。

c_{i,j} のうち少なくとも 2 つは 'B' である。

出力形式

答えを表す整数を 1 行に出力せよ。

入力例 1

3 3
B.B
..B
.BB

出力例 1

4

(1,1) と (3,3) の 2 点間が最長です。

入力例 2

4 3
B..
B..
...
...

出力例 2

1

隣り合う位置が最長になる場合もあります。

入力例 3

6 6
...B..
B.B.B.
.B.B.B
...B.B
.B..B.
..B...

出力例 3

7

Solution in C# (judge verdict: Accepted)

using static System.Math;
using System.Linq;
using System.Collections.Generic;
using System;

public class P
{
    public int x { get; set; }
    public int y { get; set; }
}

public class hello
{
    public static int h, w;
    public static void Main()
    {
        string[] line = Console.ReadLine().Trim().Split(' ');
        h = int.Parse(line[0]);
        w = int.Parse(line[1]);
        var ss = new string[h];
        var used = new bool[h, w];
        for (int i = 0; i < h; i++) ss[i] = Console.ReadLine().Trim();
        var ps = getList(ss);
        getAns(ps);
    }
    static List<P> getList(string[] ss)
    {
        var res = new List<P>();
        var used = new bool[h, w];
        for (int i = 0; i < h; i++)
        {
            for (int j = 0; j < w; j++)
                if (ss[i][j] == 'B')
                    if (!used[i, j]) { used[i, j] = true; res.Add(new P { x = i, y = j }); break; }
            for (int j = w - 1; j >= 0; j--)
                if (ss[i][j] == 'B')
                    if (!used[i, j]) { used[i, j] = true; res.Add(new P { x = i, y = j }); break; }
        }
        for (int i = 0; i < w; i++)
        {
            for (int j = 0; j < h; j++)
                if (ss[j][i] == 'B')
                    if (!used[j, i]) { used[j, i] = true; res.Add(new P { x = j, y = i }); break; }
            for (int j = h - 1; j >= 0; j--)
                if (ss[j][i] == 'B')
                    if (!used[j, i]) { used[j, i] = true; res.Add(new P { x = j, y = i }); break; }
        }
        return res;
    }
    static void getAns(List<P> ps)
    {
        var res = 0;
        var psc = ps.Count();
        for (int i = 0; i < psc - 1; i++)
            for (int j = i + 1; j < psc; j++)
                res = Max(res, Abs(ps[i].x - ps[j].x) + Abs(ps[i].y - ps[j].y));
        Console.WriteLine(res);
    }
}