第四题:恺撒的规划(NOIP2009测试试题12.08)

 恺撒的规划

亚特兰蒂斯是一块富饶美丽的土地。恺撒大帝率领他的大军,经过了一整年的浴血奋战,

终于将它纳入了罗马帝国的版图。然而,长期的战火彻底抹去了这里的繁华,昔日的富庶之地如今一片荒芜。恺撒大帝作为一位有着雄才大略的君主,决心在战争的废墟上建起一座更为宏伟的城市。所以,在建城之前,他需要对整个城市进行规划。

  亚特兰蒂斯是一块矩形平原,恺撒准备在上面修建一些建筑。为了规划方便,他将矩形划分成N*M格。棘手的是,部分古老的神庙残存下来,散布在某些格子内。亚特兰蒂斯的原住民原本就十分信奉神灵,而这些经过战火洗礼的神庙更是被他们视为圣物,是万万不能拆除的,否则将激起民愤,甚至引发暴动。恺撒深知这一点,因此,他的新建筑在选址时要避开这些神庙。

  假设新的建筑物有P种规格,每种建筑物都是正方形的,占地为Ti *Ti格 (1<=i<=P)。恺撒想知道对于每种规格的建筑,有多少种不同的合适选址方案(一种合适的选址方案指的是在该建筑所占的正方形区域内不存在神庙)。作为他的内务部长,这个光荣而艰巨的任务自然交给你来完成。

输入:

  输入文件第一行包含三个数,分别代表N,M,P (1<=N,M<=2000,1<=P<=1000)。随后的n行,每行有m个0或1(1表示该格为废墟,0表示该格有神庙)。接下来的P行每行有一个整数  (1< <=max(M,N)),代表的第i种建筑物的边长。

输出:

  输出文件有P行,每行一个整数,第i行的数代表边长为Ti 的建筑物选址方案数。

【样例输入】(squares.in):

4 4 2

1011

1111

1110

1110

2

3

【样例输出】(squares.out):

5

1

测试结果如下:

/******************************************************************************************************
 ** Copyright (C) 2011.07.01-2013.07.01
 ** Author: famousDT <13730828587@163.com>
 ** Edit date: 2011-10-21
******************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>//abs,atof(string to float),atoi,atol,atoll
#include <math.h>//atan,acos,asin,atan2(a,b)(a/b atan),ceil,floor,cos,exp(x)(e^x),fabs,log(for E),log10
#include <vector>
#include <queue>
#include <map>
#include <time.h>
#include <set>
#include <list>
#include <stack> 
#include <string>
#include <iostream>
#include <assert.h>
#include <string.h>//memcpy(to,from,count
#include <ctype.h>//character process:isalpha,isdigit,islower,tolower,isblank,iscntrl,isprll
#include <algorithm>
using namespace std;

typedef long long ll;

#define MY_PI acos(-1)
#define MY_MAX(a, b) ((a) > (b) ? (a) : (b))
#define MY_MIN(a, b) ((a) < (b) ? (a) : (b))
#define MY_MALLOC(n, type) ((type *)malloc((n) * sizeof(type)))
#define MY_ABS(a) (((a) >= 0) ? (a) : (-(a)))
#define MY_INT_MAX 0x7fffffff

/*==========================================================*\
| 
\*==========================================================*/
#define N 2000 + 1
int d[N][N];
int main()
{
    FILE *in,*out;
    in = fopen("squares.in","rt");
    out = fopen("squares.out","wt"); 
    int m, n, p;
    int i, j;
    char c;
    while (fscanf(in, "%d%d%d%c", &m, &n, &p, &c) == 4) {
        for (i = 0; i <= N; ++i) d[0][i] = d[i][0] = 0;
        for (i = 1; i <= m; ++i) {
            for (j = 1; j <= n; ++j) {
                fscanf(in, "%c", &c);
                d[i][j] = d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1] + c - '0';
            }
            fscanf(in, "%c", &c);
        }
        while (p--) {
            int x, t;
            int ans = 0;
            fscanf(in, "%d", &x);
            t = x * x;
            for (i = x; i <= m; ++i) {
                for (j = x; j <= n; ++j) {
                    if (d[i][j] - d[i - x][j] - d[i][j - x] + d[i - x][j - x] == t)
                        ++ans;
                }
            }
            fprintf(out, "%d\n", ans);
        }
    }
    fclose(in);
    fclose(out);
    return 0;
}
/*
4 4 2
1011
1111
1110
1110
2
3
*/


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值