2014
11-30

# Searchlights

There is a piece of grids land of size n×m. Chandler and his team take responsibility to guard it. There are some searchlights on some pieces and each of them has a capability to lighten a distance towards four directions: north, south, east and west. Different searchlight has different lightening capability shown in levels. Searchlight with level k means that it can lighten k grids (including the gird that the searchlight stands in) along any of the four directions. Shown in following figure, there is a searchlight of level 3 and the shadow grids are ones that can be lightened by it. Particularly, searchlight of level 1 means that it can only lighten the grid in which the searchlight stands.

Each searchlight has a maximum level. You can decrease a searchlight’s level to save the energy. A searchlight whose maximum level is k can be turned to level k, k-1, k-2, …, 1 and 0. Level 0 means turning off the searchlight.

A grid is well-guarded if and only if at least one of the following two conditions is satisfied:
1.There is a searchlight in this grid, and it is not switched to level 0 (the light is on).
2.The grid is lightened by at least two searchlights. One lightens it in horizontal direction (east or west), and another lightens it in vertical direction (north or south).

Chandler asks you to help finding a solution that he can turn on some of the searchlights so that:
1.All the grids are well-guarded.
2.All the searchlights turned on are in a same level.
3.That same level mentioned above is as small as possible.
More specifically, if you choose a same level Q, then all the searchlights whose maximum level are less than Q have to be turned off. Please help him to find a solution with the minimum same level.

The input file contains several test cases.

For each test case, the first line is two integers n and m, representing a grids land of size n×m. (0<n<=100, 0<m<=10000). Following n lines describe an n×m matrix in which ai,j means the maximum level of the searchlight in grid (i, j). ai,j can be zero, which means there is no searchlight on that grid. For all the cases, ai, j<=10000.

The input file ends with a line containing two zeros.

The input file contains several test cases.

For each test case, the first line is two integers n and m, representing a grids land of size n×m. (0<n<=100, 0<m<=10000). Following n lines describe an n×m matrix in which ai,j means the maximum level of the searchlight in grid (i, j). ai,j can be zero, which means there is no searchlight on that grid. For all the cases, ai, j<=10000.

The input file ends with a line containing two zeros.

2 2
0 2
3 0
2 2
0 2
1 0
0 0

2
NO ANSWER!

#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
#define inf 100000

int n,m;
int a[101][10010];
int r[101][10010],c[101][10010];
int que[10010][2],p,q;

inline int max(int x,int y){return x<y?y:x;}
inline int min(int x,int y){return x<y?x:y;}

int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if (n==0 && m==0) return 0;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
r[i][j]=c[i][j]=inf;
}
int ans=-1;
while(1)
{
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
r[i][j]=c[i][j]=inf;

for (int i=1;i<=n;i++)
{
p=1;q=0;
for (int j=1;j<=m;j++)
{
while(p<=q && a[i][j]+j-1>=que[q][1]) q--;
que[++q][0]=j;que[q][1]=a[i][j]+j-1;
while(p<=q && que[q][1]<j) q--;
if (p<=q)
r[i][j]=j-que[q][0]+1;
}
p=1;q=0;
for (int j=m;j>=1;j--)
{
while(p<=q && j-a[i][j]+1<=que[q][1]) q--;
que[++q][0]=j;que[q][1]=j-a[i][j]+1;
while(p<=q && que[q][1]>j) q--;
if (p<=q)
r[i][j]=min(r[i][j], que[q][0]-j+1);
}
}

for (int j=1;j<=m;j++)
{
p=1;q=0;
for (int i=1;i<=n;i++)
{
while(p<=q && a[i][j]+i-1>=que[q][1]) q--;
que[++q][0]=i;que[q][1]=a[i][j]+i-1;
while(p<=q && que[q][1]<i) q--;
if (p<=q) c[i][j]=i-que[q][0]+1;
}
p=1;q=0;
for (int i=n;i>=1;i--)
{
while(p<=q && i-a[i][j]+1<=que[q][1]) q--;
que[++q][0]=i;que[q][1]=i-a[i][j]+1;
while(p<=q && que[q][1]>i) q--;
if (p<=q) c[i][j]=min(c[i][j], que[q][0]-i+1);
}
}

int tmp=0;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
tmp=max(tmp,max(c[i][j],r[i][j]));
}
if (tmp==ans) break;
ans=tmp;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
a[i][j]=(a[i][j]<tmp?0:a[i][j]);
}
}
if (ans<inf) printf("%d\n",ans);
}