USACO 5.3 Big Barn
Farmer John wants to place a big square barn on his square farm. He hates to cut down trees on his farm and wants to find a location for his barn that enables him to build it only on land that is already clear of trees. For our purposes, his land is divided into N x N parcels. The input contains a list of parcels that contain trees. Your job is to determine and report the largest possible square barn that can be placed on his land without having to clear away trees. The barn sides must be parallel to the horizontal or vertical axis.
EXAMPLE
Consider the following grid of Farmer John's land where `.' represents a parcel with no trees and `#' represents a parcel with trees:
1 2 3 4 5 6 7 8 1 . . . . . . . . 2 . # . . . # . . 3 . . . . . . . . 4 . . . . . . . . 5 . . . . . . . . 6 . . # . . . . . 7 . . . . . . . . 8 . . . . . . . .
The largest barn is 5 x 5 and can be placed in either of two locations in the lower right part of the grid.
PROGRAM NAME: bigbrn
INPUT FORMAT
Line 1: | Two integers: N (1 <= N <= 1000), the number of parcels on a side, and T (1 <= T <= 10,000) the number of parcels with trees |
Lines 2..T+1: | Two integers (1 <= each integer <= N), the row and column of a tree parcel |
SAMPLE INPUT (file bigbrn.in)
8 3 2 2 2 6 6 3
OUTPUT FORMAT
The output file should consist of exactly one line, the maximum side length of John's barn.
SAMPLE OUTPUT (file bigbrn.out)
5
————————————————————————————题解
我心里一凉……
saffah刷过USACO?
……这不是重点,然后这道题只要存一个二维前缀和就可以O(1)以i,j为左上角,k为边长的正方形是否合法,然后枚举的话枚举每一个没有树的点,再枚举长度
n^3肯定超时,那么我们第一个优化就是如果当前长度找不到后面也不用扩展了,直接跳出,这样在树比较少图比较大的时候是超时的
第二个优化比较重要,是从左边位置扩展长度-1开始枚举
然后,一二优化加起来,枚举个数不会超过3,因为这个位置要么是左边位置扩展长度-1,要么等于左边位置扩展长度,要么是左边位置扩展长度+1
然后就过了
不过在这里再提一个小想法,二分长度也许也能过
程序看着像一个N^3,实则不然
1 /* 2 ID: ivorysi 3 LANG: C++ 4 PROG: bigbrn 5 */ 6 #include <iostream> 7 #include <cstdio> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <set> 12 #include <vector> 13 #include <string.h> 14 #include <cmath> 15 #include <stack> 16 #define siji(i,x,y) for(int i=(x);i<=(y);++i) 17 #define gongzi(j,x,y) for(int j=(x);j>=(y);--j) 18 #define xiaosiji(i,x,y) for(int i=(x);i<(y);++i) 19 #define sigongzi(j,x,y) for(int j=(x);j>(y);--j) 20 #define inf 0x3f3f3f3f 21 #define ivorysi 22 #define mo 97797977 23 #define hash 974711 24 #define base 47 25 #define pss pair<string,string> 26 #define MAXN 5000 27 #define fi first 28 #define se second 29 #define pii pair<int,int> 30 #define esp 1e-8 31 typedef long long ll; 32 using namespace std; 33 int n,m; 34 int a[1005][1005],sum[1005][1005],sol[1005][1005],ans; 35 bool check(int x,int y,int k) { 36 return (sum[x+k-1][y+k-1]+sum[x-1][y-1]-sum[x-1][y+k-1]-sum[x+k-1][y-1])==0; 37 } 38 void solve() { 39 scanf("%d%d",&n,&m); 40 siji(i,0,n+1) {a[i][0]=1;a[i][n+1]=1;a[0][i]=1;a[n+1][i]=1;}//边上种上一圈树 41 int x,y,t; 42 siji(i,1,m) { 43 scanf("%d%d",&x,&y); 44 a[x][y]=1; 45 } 46 siji(i,0,n+1) sum[i][0]=a[i][0]; 47 siji(i,0,n+1) { 48 49 siji(j,1,n+1) { 50 sum[i][j]=sum[i][j-1]+a[i][j]; 51 } 52 } 53 siji(i,1,n+1) { 54 siji(j,0,n+1) { 55 sum[i][j]+=sum[i-1][j]; 56 } 57 } 58 siji(i,1,n) { 59 siji(j,1,n) { 60 if(a[i][j]==1) continue; 61 t=max(sol[i][j-1]-1,1); 62 siji(k,t,n) { 63 if(!check(i,j,k)) break; 64 sol[i][j]=k; 65 } 66 ans=max(ans,sol[i][j]); 67 } 68 } 69 printf("%d\n",ans); 70 } 71 int main(int argc, char const *argv[]) 72 { 73 #ifdef ivorysi 74 freopen("bigbrn.in","r",stdin); 75 freopen("bigbrn.out","w",stdout); 76 #else 77 freopen("f1.in","r",stdin); 78 #endif 79 solve(); 80 return 0; 81 }