链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
帕秋莉掌握了一种土属性魔法
这种魔法可以在一片k×k大小的一个正方形区域内产生地震
但是如果某片即将产生地震的区域内有建筑物,帕秋莉会停止施法
整个地图大小为n×m,其中一些地方有建筑
请问有多少种可能的情况,使得帕秋莉会停止施法
输入描述:
第一行三个数n, m, k,意义见描述 接下来一个n×m的01矩阵表示这篇区域的情况,1表示这个地方有建筑
输出描述:
输出一个数表示答案
示例1
输入
4 4 2 1000 0100 0000 0001
输出
5
这个题目用二维前缀和来写,我这个写法没有构造差分数组,其实要是涉及到把对于一个区间的操作转化成对点的操作是应该构造差分数组的,这个把题写完再说。思路是先读入数据,这里用字符来装,然后-‘0‘转化为整数,这里可别用整数int来装!!!,因为这样的话1000会被按照一个整数读入。然后构造sum数组,其意义是由原点到这里的二维前缀和,然后通过前缀和的操作检查区间内和是否为0,不为0即获得一个解。
下面是代码:
#include <cstdio>
#include <bits/stdc++.h>
using namespace std;
const int N=10006;
int p[N][N],sum[N][N];
int main()
{
int n,m,k;
cin>>n>>m>>k;
int res=0;
//cout<<n<<m<<k<<"\n";
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
char a;
cin>>a;
p[i][j]=a-'0';
}
}//输入是成功的
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
sum[i][j]=p[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
}
}//这个不是差分数组哈。。这个数组的意义是由原点到这一点的前缀和
for(int i=1;i<=n-k+1;i++)
{
for(int j=1;j<=m-k+1;j++)
{
int temp=sum[i-1][j-1]+sum[i+k-1][j+k-1]-sum[i+k-1][j-1]-sum[i-1][j+k-1];//通过前缀和来检查区间
if(temp!=0)
res++;
}
}
cout<<res;
return 0;
}
下面再来说说前缀和与差分数组的事
现在有一个二维数组,如果想对它里面的一个区域都加上一个常数,那么应该怎样操作呢?可以构造差分数组,使差分数组的前缀和就等于数组中这个元素。公式是这样的:b[i][j]=a[i][j]−a[i−1][j]−a[i][j−1]+a[i−1][j−1],b数组就是差分数组,a是原数组。然后要对某个区域内的元素加一个常数可以表述为:
b[x1][y1]+=c;
b[x2+1][y1]-=c;
b[x1][y2+1]-=c;
b[x2+1][y2+1]+=c;