1387 农场

题目地址:http://acm.uestc.edu.cn/problem.php?pid=1367&cid=98

 

恩 水题。确实水题。但俺没过。

因为数据比较大 简单枚举就爆掉了 要用类似dp的方法 定义dp[i][j]表示 (1,1) - (i,j) 这一区域内有多少个点被已经种有植物。那么

在求 (i-A+1, j-B+1) - (i,j) 这块 A*B 区域内有无被占用的点时,只需做一次加减运算。 种有植物的点的点数为 (dp[i][j]+ dp[i-A][j-B]) - (dp[i-A][j]+ dp[i][j-B])

按照这一思路用两重循环就能得到答案 要注意的只有 当A==B的时候ans要除2;

代码
#include <stdio.h>

#include
<string.h>

int badfrm[1002][1002];
int farm[1002][1002];

int main()
{
int T, N, r, c, p, q, i, j, x, y, A, B, k, cas = 1;
scanf(
"%d", &T);
while (T--) {
memset(badfrm,
0, sizeof(badfrm));
memset(farm,
0, sizeof(farm));
scanf(
"%d%d%d%d", &r, &c, &p, &q);
for (i = 0; i < p; i++) {
scanf(
"%d%d", &x, &y);
badfrm[x][y]
= 1;
}

for (i = 1; i <= r; i++) {
farm[
1][i] = farm[1][i - 1] + badfrm[1][i];
}
for (i = 1; i <= c; i++) {
farm[i][
1] = farm[i - 1][1] + badfrm[i][1];
}

for (i = 2; i <= r; i++) {
for (j = 2; j <= c; j++) {
farm[j][i]
= farm[j][i - 1] + farm[j - 1][i] - farm[j - 1][i - 1] + badfrm[j][i];
}
}
printf(
"Case #%d:\n", cas++);
for (k = 0; k < q; k++) {
int ans = 0, isbad = 0;
scanf(
"%d%d", &A, &B);
for (i = 0; i <= r - A; i++) {
for (j = 0; j <= c - B; j++) {
isbad
= farm[j][i] + farm[j + B][i + A] - farm[j + B][i] - farm[j][i + A];
if (isbad == 0)
ans
++;
}
}

for (i = 0; i <= r - B; i++) {
for (j = 0; j <= c - A; j++) {
isbad
= farm[j][i] + farm[j + A][i + B] - farm[j + A][i] - farm[j][i + B];
if (isbad == 0)
ans
++;
}
}
if (A == B)
ans
/= 2;
printf(
"%d\n", ans);
}
}
return 0;
}

 

posted @ 2011-01-17 20:07  luxury  阅读(127)  评论(0编辑  收藏  举报