CCF 202104-2 邻域均值

暴力70(近几年都是),想要100肯定不能这么简单。

自己想的优化方法是,在计算每个位置的平均值时,如果左右有超界的,则停止向这个方向行动。

但是这个优化方法依旧超时(😓)

找了第一个方法,文章说每次删掉最后一行,添加新的一行,使用先前计算的数据,不需要每次都从头计算。

是个方法但是代码自己没写出来,感觉思路乱了((lll¬ω¬))

又找了一个方法,使用二维前缀和!哦!这个又简单又好理解。是个好方法!

知识点:前缀和

前缀和的优势:以O(1)的时间复杂度得到某块区间的总和

题目特点:多次询问的,计算区间总和的。

对于本题目来说,还有一个小点,计算范围里的数字个数,可以学习一下。自己写的太乱。

AC代码:

#include<iostream>
using namespace std;
int sum[605][605];
int dark[605][605];
int main() {
    int n,l,r,t;
    cin >> n >> l >> r >> t;
    int temp = 0;
    for(int i = 1 ; i <= n ; i++) {
        for(int j = 1 ; j <= n ; j++) {
            cin >> temp;
            sum[i][j] = temp + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1];
        }
    }
    int ans = 0;
    for(int i = 1 ; i <= n ; i++) {
        for(int j = 1 ; j <= n ; j++) {
            int x1 = max(i-r,1), y1 = max(j-r,1);//注意  卡在了这里 
            int x2 = min(i+r,n), y2 = min(j+r,n);
            int avr = (sum[x2][y2] - sum[x2][y1-1]- sum[x1-1][y2] + sum[x1-1][y1-1]);
            int num = (x2 - x1 + 1) * (y2 - y1 + 1);
            if(avr <= t * num) {
                ans++;
                dark[i][j] = 1;
            }
        }
    }

    cout << ans << '\n';
//    for(int i = 1 ; i <= n ; i++) {
//        for(int j = 1 ; j <= n ; j++) {
//            cout << sum[i][j] << ' ';
//        }
//        cout << '\n';
//    }
//
//    for(int i = 1 ; i <= n ; i++) {
//        for(int j = 1 ; j <= n ; j++) {
//            cout << dark[i][j] << ' ';
//        }
//        cout << '\n';
//    }
}

参考:(14条消息) CCF 202104-2 邻域均值【二维前缀和】_memcpy0的博客-CSDN博客

posted @ 2022-07-14 09:40  夏莱发电厂的Sensei  阅读(87)  评论(0)    收藏  举报