usaco5.3.4 Big Barn

一 原题

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 trees
Lines 2..T+1:Two integers (1 <= each integer <= N), therow 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 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: bigbrn
LANG: C++

Compiling...
Compile: OK

Executing...
   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 your submission #5 for this problem. Congratulations!


AC代码:

/*
ID:maxkibb3
LANG: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;
	// Left
	for(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;
		}
	}
	// Dp
	for(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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值