EOJ Monthly 2020.7 C (二维前缀和)

题面

屏幕是一个 行 列(下简称 )的矩阵。屏保图像是一个 () 的黑白图像。 表示白色, 表示黑色。当屏保图像显示在屏幕上时,白色对应的像素发光,屏幕上其余的所有像素不发光 (显然, 屏保至少有一点发光, 也就是图像中至少有一个 )。

每分钟,这个屏保图像会等概率地随机出现在屏幕上的任何一个合法位置(合法位置满足:屏保图像上的每一个像素不超过屏幕边界,图像不缩放,不旋转)。因此学过数学的同学肯定会发现,屏幕一共有 种等概率的显示状态。

Cuber QQ 发现,一个像素的衰减系数和它的发光时长成正比。为了方便后续研究,Cuber QQ 规定屏幕上衰减程度最大(也就是发光时长最长)的像素的衰减系数为 ,其余像素的衰减系数以此为基准可以相应得出。

给定屏幕尺寸和屏保图案,请你求出经过足够长的时间,每一个像素期望的衰减系数。

输入格式
第一行 (, , , )。

接下来一个 的 矩阵表示屏保图案, 且矩阵中至少有一个 。

输出格式
输出一个 的整数矩阵表示每个像素的衰减系数的整数部分 (即将衰减系数从小数向下取整)。根据题目描述,矩阵中的最大值显然为 。

思路

我们对这个矩阵做一个差分,然后把每个可能到达的区域进行一个区间处理,然后累加二维前缀和,最后取最大值输出。

代码实现

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#include<stack>
using namespace std;
const int maxn=4001;

int dif[maxn][maxn];

int main () {
    int a,b,n,m;
    cin>>n>>m>>a>>b;
    for (int i=1;i<=n;i++)
     for (int j=1;j<=m;j++) {
         int num;
         cin>>num;
         if (num) {
             int x=b-m+j; int y=a-n+i;
             dif[i][j]++;
             dif[i][x+1]--;
             dif[y+1][j]--;
             dif[y+1][x+1]++;
         }
     }
    int ans=0;
    for (int i=1;i<=a;i++)
     for (int j=1;j<=b;j++) {
         dif[i][j]+=dif[i-1][j]+dif[i][j-1]-dif[i-1][j-1];
         ans=max (ans,dif[i][j]);
     }

    for (int i=1;i<=a;i++)
     for (int j=1;j<=b;j++) {
        printf ("%d%c",100*dif[i][j]/ans,j==b?'\n':' ');
     }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hhlya/p/13378916.html