OLED 解题报告

题目地址:https://acm.ecnu.edu.cn/contest/292/problem/C/

考虑计算每个像素的贡献,如果对图像每个可能位置进行枚举,则时间复杂度为 O ( n m a b ) O(nmab) O(nmab),因此需要考虑前缀和。

对于某一行,前 b − m + 1 b-m+1 bm+1列的贡献可直接由前缀和求出,因为对于第 j j j列,其等概率可能地被图像第 1 1 1 j j j列覆盖,而对于后 m − 1 m-1 m1列,它不可能被图像的第 1 1 1 j − ( b − m + 1 ) j-(b-m+1) j(bm+1)列覆盖,因此需要减去相应的贡献。

同理,对于某一列,前 a − n + 1 a-n+1 an+1行的贡献可直接由前缀和求出;而后面的 n − 1 n-1 n1列也需要减去相应的贡献。

那么我们可以定义一个初始数组表示图像未考虑减去贡献前的前缀和,然后用另一数组进行相应的计算即可,最后将最大值作为基准转换为百分数。时间复杂度 O ( a b ) O(ab) O(ab).

代码:

#include
#include
using namespace std;
 int n,m,a,b;
 int maximum;
 int t[3841][2161];
 int map[3841][2161];
int main()
{
 scanf("%d%d%d%d",&n,&m,&a,&b);
 for (int i = 1;i <= n;i ++)
  for (int j = 1;j <= m;j ++)
   scanf("%d",&t[i][j]);
 for (int i = 1;i <= a;i ++)
 {
  for (int j = 1;j <= b;j ++)
  {
   t[i][j] += t[i][j - 1];
   map[i][j] = t[i][j];
  }
  for (int j = b - m + 2;j <= b;j ++)
   t[i][j] -= map[i][j - (b - m + 1)];
  for (int j = 1;j <= b;j ++)
  {
   t[i][j] += t[i - 1][j];
   map[i][j] = t[i][j];
  }
 }
 for (int i = a - n + 2;i <= a;i ++)
  for (int j = 1;j <= b;j ++)
   t[i][j] -= map[i - (a - n + 1)][j];
 for (int i = 1;i <= a;i ++)
  for (int j = 1;j <= b;j ++)
   maximum = max(maximum,t[i][j]);
 for (int i = 1;i <= a;i ++)
 {
  for (int j = 1;j <= b;j ++)
   printf("%d ",int(double(t[i][j]) / maximum * 100));
  printf("\n");
 }
 return 0;
} 

你可能感兴趣的:(递推与动态规划)