Big Barn
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 21 Accepted Submission(s): 10
Problem Description
农夫John想在他的正方形农场上建一个正方形谷仓。他不想在他的农场砍伐树木,所以他要为他的谷仓找一个位置,使他在没有树的地方建谷仓。农场被划分为N×N(N≤1000)块。输入给出这些块的一个列表,在有些块内生长着树。请您找出最大的一个不包含任何树的一块正方形场地。谷仓的边必须与水平轴或垂直轴平行。
例如,下面给出的是农夫John的土地,其中`.' 表示在这个块中没有树木,而`#'表示这个块中有树木:
1 2 3 4 5 6 7 8
1 . . . . . . . .
2 . # . . . # . .
3 . . . . . . . .
4 . . . . . . . .
5 . . . . . . . .
6 . . # . . . . .
7 . . . . . . . .
8 . . . . . . . .
最大的谷仓是5×5,可修建在网格右下方的两个位置之一。
例如,下面给出的是农夫John的土地,其中`.' 表示在这个块中没有树木,而`#'表示这个块中有树木:
1 2 3 4 5 6 7 8
1 . . . . . . . .
2 . # . . . # . .
3 . . . . . . . .
4 . . . . . . . .
5 . . . . . . . .
6 . . # . . . . .
7 . . . . . . . .
8 . . . . . . . .
最大的谷仓是5×5,可修建在网格右下方的两个位置之一。
Input
有多组输入数据.(少于20组)
对于每一组数据,首先给出两个整数:N(1≤N≤1000),块的数量;和T(1≤T≤10000),有树的块的数量。第2行到第T+1行,每行两个整数,在区间[1, N]中取值,表示有树的一个块的行和列。
对于每一组数据,首先给出两个整数:N(1≤N≤1000),块的数量;和T(1≤T≤10000),有树的块的数量。第2行到第T+1行,每行两个整数,在区间[1, N]中取值,表示有树的一个块的行和列。
Output
对于每一组数据,单独输出一行表示John的正方形谷仓的最大边长。
Sample Input
8 3 2 2 2 6 6 3
Sample Output
5
题意:中文很清楚。
思路:用二分的方法暴查找最大空正方形的边长。对于每次查找运用类似于在二维数组里查找子矩阵的方法。设有树的地方为1,首先用sum[i][j]表示第i行到第j列的和,然后对于每次查找可以很快得出一个num[k]为某两列之间的每行的和,然后就可以用一维的数组计算是否存在连续的空n*n矩阵。
AC代码如下:
#include<cstdio>
#include<cstring>
using namespace std;
int tree[1010][1010];
int sum[1010][1010];
int main()
{ int i,j,k,n,m,x,y,ans,l,r,p,l2,r2,res;
while(~scanf("%d%d",&n,&m))
{ memset(tree,0,sizeof(tree));
for(i=1;i<=m;i++)
{ scanf("%d%d",&x,&y);
tree[x][y]=1;
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
sum[i][j]=sum[i][j-1]+tree[i][j];
ans=0;
l2=1;r2=n;
while(l2<r2)
{ i=(l2+r2+1)/2;
res=0;ans=0;
for(j=1;j<=n-i+1;j++)
{ l=j;r=j+i-1;p=0;
for(k=1;k<=n;k++)
{ if(sum[k][r]-sum[k][l-1]>0)
p=0;
else
{ p++;
if(p>=i)
{ ans=i;
break;
}
}
}
}
if(ans>0)
l2=i;
else
r2=i-1;
}
printf("%d\n",l2);
}
}