USACO 5.3 Big Barn

Big Barn
A Special Treat

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 }

 

posted @ 2017-02-17 11:43  sigongzi  阅读(360)  评论(0编辑  收藏  举报