usaco5.3.4 Big Barn

来源:互联网 发布:android mac 编辑:程序博客网 时间:2024/05/16 13:05

一 原题

Big Barn
A Special Treat

Farmer John wants to place a big square barn on his square farm. Hehates to cut down trees on his farm and wants to find a location for hisbarn that enables him to build it only on land that is already clear oftrees. For our purposes, his land is divided into N x N parcels. The inputcontains a list of parcels that contain trees. Your job is to determineand report the largest possible square barn that can be placed on his landwithout having to clear away trees. The barn sides must be parallel to thehorizontal or vertical axis.

EXAMPLE

Consider the following grid of Farmer John's land where `.' representsa 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 locationsin the lower right part of the grid.

PROGRAM NAME: bigbrn

INPUT FORMAT

Line 1:Two integers: N (1 <= N <= 1000), thenumber of parcels on a side, and T (1 <= T <= 10,000) the number ofparcels with treesLines 2..T+1:Two integers (1 <= each integer <= N), therow and column of a tree parcel

SAMPLE INPUT (file bigbrn.in)

8 32 22 66 3

OUTPUT FORMAT

The output file should consist of exactly one line, the maximum side lengthof John's barn.

SAMPLE OUTPUT (file bigbrn.out)

5


二 分析

动规。我记录了三个数组:Left[i][j]代表从坐标为(i,j)的点开始向左数最多有多少个连续的空地,Up[i][j]为向上数的对应值,Dp[i][j]代表以坐标(i,j)的点为右下角的最大空地正方形边长。状态转移方程:Dp[i][j] = min(Dp[i-1][j-1]+1, Left[i][j], Up[i][j])。结果写出来要开4个1M的数组,爆内存了。。(exit '127')偷懒全部改成short就过了。改成滚动应该可以稳稳地过。

交完想到只开一个数组的方法,只需要定义Dp数组,含义相同,Dp[i][j] = min(Dp[i-1][j-1] + 1, Dp[i-1][j], Dp[i][j-1])


三 代码

运行结果:

USER: Qi Shen [maxkibb3]TASK: bigbrnLANG: C++Compiling...Compile: OKExecuting...   Test 1: TEST OK [0.000 secs, 11084 KB]   Test 2: TEST OK [0.000 secs, 11084 KB]   Test 3: TEST OK [0.000 secs, 11084 KB]   Test 4: TEST OK [0.000 secs, 11084 KB]   Test 5: TEST OK [0.000 secs, 11084 KB]   Test 6: TEST OK [0.000 secs, 11084 KB]   Test 7: TEST OK [0.000 secs, 11084 KB]   Test 8: TEST OK [0.000 secs, 11084 KB]   Test 9: TEST OK [0.000 secs, 11084 KB]   Test 10: TEST OK [0.011 secs, 11084 KB]   Test 11: TEST OK [0.011 secs, 11084 KB]   Test 12: TEST OK [0.011 secs, 11084 KB]   Test 13: TEST OK [0.022 secs, 11084 KB]   Test 14: TEST OK [0.022 secs, 11084 KB]   Test 15: TEST OK [0.022 secs, 11084 KB]All tests OK.

Your program ('bigbrn') produced all correct answers! This is yoursubmission #5 for this problem. Congratulations!


AC代码:

/*ID:maxkibb3LANG:C++PROB:bigbrn*/#include<cstdio>const int MAXN = 1005;int N, T;short Left[MAXN][MAXN];short Up[MAXN][MAXN];bool Map[MAXN][MAXN];short Dp[MAXN][MAXN];int min(int _a, int _b, int _c) {if(_a <= _b && _a <= _c) return _a;else if(_b <= _a && _b <= _c) return _b;else return _c;}void init() {scanf("%d%d", &N, &T);for(int i = 0; i < T; i++) {int x, y;scanf("%d%d", &x, &y);Map[x][y] = true;}}void solve() {int i, j, ans = 0;// Leftfor(i = 1; i <= N; i++) for(j = 1; j <= N; j++) {if(Map[i][j]) {Left[i][j] = Up[i][j] = 0;}else {Left[i][j] = Left[i][j - 1] + 1;Up[i][j] = Up[i - 1][j] + 1;}}// Dpfor(i = 1; i <= N; i++)for(j = 1; j <= N; j++) {Dp[i][j] = min(Dp[i - 1][j - 1] + 1, Left[i][j], Up[i][j]);if(Dp[i][j] > ans) ans = Dp[i][j];}printf("%d\n", ans);}int main() {freopen("bigbrn.in", "r", stdin);freopen("bigbrn.out", "w", stdout);init();solve();return 0;}


0 0