ccfcsp 22

173 阅读1分钟

b.邻域均值

分析

  1. 前缀和求一遍
  2. 题目的所要求的点的范围,其实就是找一下矩阵左上角的坐标,和右下角的坐标。直接算这个矩阵的前缀和就行了。

Code

python

def solve(x1,y1,x2,y2):
    return b[x2][y2] - b[x2][y1-1] - b[x1-1][y2] + b[x1-1][y1-1]

n,l,r,t=map(int, input().split())
N=n+2
b=[[0]*N for i in range(N)]
for i in range(1,n+1):
    temp=list(map(int, input().split()))
    for j in range(1,n+1):
        tmp = temp[j-1]
        b[i][j] = b[i-1][j] + b[i][j-1]-b[i-1][j-1] + tmp

res=0
for i in range(1,n+1):
    for j in range(1,n+1):
        x1=max(1,-r+i)
        x2=min(r+i,n)
        y1=max(1, -r+j)
        y2=min(n, r+j)
        if solve(x1, y1, x2, y2) <=t*(x2-x1+1)*(y2-y1+1):
            res+=1
print(res)

cpp

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
const int N = 610;
int b[N][N], res;

int solve(int x1, int y1, int x2, int y2) { return b[x2][y2] - b[x2][y1 - 1] - b[x1 - 1][y2] + b[x1 - 1][y1 - 1]; }

int main() {
    int n, l, r, t;
    scanf("%d%d%d%d", &n, &l, &r, &t);


    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; ++j) {
            int tmp;
            scanf("%d", &tmp);
            b[i][j] = b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1] + tmp;
        }
    }

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            int x1 = max(1, i - r), x2 = min(n, i + r);
            int y1 = max(1, j - r), y2 = min(n, j + r);
            if (solve(x1, y1, x2, y2) <= t * (y2 - y1 + 1) * (x2 - x1 + 1))
                res++;
        }
    }
    printf("%d\n", res);
    return 0;
}