如果按照公式直接计算,会超时
这里有2个技巧:1、利用积分图像 2、方差的公式变换 s^2=1/n[(x1^2+x2^2+...+xn^2)-nx']
代码如下,但是不知道为什么总是WA,实在是找不到问题所在
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
#include<math.h>
using namespace std;
double calVar(vector<vector<int> >& image,vector<vector<int> >& interalMap,vector<vector<int> >& squareInteralMap,int x,int y,int p,int N)
{
int xbegin=max(1,x-p),xend=min(N,x+p);
int ybegin=max(1,y-p),yend=min(N,y+p);
int nums=(xend-xbegin+1)*(yend-ybegin+1);
double avg=(interalMap[xend][yend]-interalMap[xbegin-1][yend]-interalMap[xend][ybegin-1]+interalMap[xbegin-1][ybegin-1])*1.0/nums;
double squareavg=(squareInteralMap[xend][yend]-squareInteralMap[xbegin-1][yend]-squareInteralMap[xend][ybegin-1]+squareInteralMap[xbegin-1][ybegin-1])*1.0/nums;
double var=0.0;
var=squareavg-avg*avg;
return var;
}
int main()
{
int n;
scanf("%d",&n);
vector<vector<int> > image(n+1,vector<int>(n+1));
vector<vector<int> > interalMap(n+1,vector<int>(n+1,0));
vector<vector<int> > squareInteralMap(n+1,vector<int>(n+1,0));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&image[i][j]);
interalMap[1][1]=image[1][1];
for(int i=2;i<=n;i++)
{
interalMap[1][i]=interalMap[1][i-1]+image[1][i];
interalMap[i][1]=interalMap[i-1][1]+image[i][1];
}
for(int i=2;i<=n;i++)
for(int j=2;j<=n;j++)
interalMap[i][j]=interalMap[i-1][j]+interalMap[i][j-1]-interalMap[i-1][j-1]+image[i][j];
squareInteralMap[1][1]=image[1][1]*image[1][1];
for(int i=2;i<=n;i++)
{
squareInteralMap[1][i]=squareInteralMap[1][i-1]+image[1][i]*image[1][i];
squareInteralMap[i][1]=squareInteralMap[i-1][1]+image[i][1]*image[i][1];
}
for(int i=2;i<=n;i++)
for(int j=2;j<=n;j++)
squareInteralMap[i][j]=squareInteralMap[i-1][j]+squareInteralMap[i][j-1]-squareInteralMap[i-1][j-1]+image[i][j]*image[i][j];
int p;
while(scanf("%d",&p)&&p)
{
double var=0.0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
var+=calVar(image,interalMap,squareInteralMap,i,j,p,n);
printf("%d\n",(int)floor(var));
}
return 0;
}