/*
* @Author: 365JHWZGo
* @Description: 邻域均值
* @Date: 2021-08-29 17:50:17
* @FilePath: \VScodeC++practice\ccf\linyujunzhi1.cpp
* @LastEditTime: 2021-08-29 20:30:04
* @LastEditors: 365JHWZGo
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <math.h>
using namespace std;
int main()
{
std::ios::sync_with_stdio(false);
int n, L, r, t, ans = 0, temp = 0;
double times = 0.0; //!!!!!times是double类型,否则后面/后为整数
cin >> n >> L >> r >> t;
int A[n][n] = {0};
int pro[n][n];
// double pp[n][n] = {0.0}; //辅助函数
//初始化
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> A[i][j];
pro[i][j] = 0;
}
}
//赋值
for (int i = 0; i < n; i++) //控制行
{
for (int j = 0; j < n; j++)//控制列
{
if (j - 1 == -1) //初始化计算每行第一列,pro[]来源
{
int ti, tj;
ti = i - r;
tj = j - r;
if (ti < 0) //当构不成全图时,从0开始
ti = 0;
if (tj < 0)//当构不成全图时,从0开始
tj = 0;
for (int x = ti; x >= 0 && x - i <= r && x < n; x++)
{
for (int y = tj; y >= 0 && y - j <= r && y < n; y++)
{
if (A[x][y] == 0)
{
times += 1.0;
continue;
}
temp += A[x][y];
times += 1.0;
}
}
pro[i][j] = temp;
}
else //其他情况
{
double ft = 0.0, ht = 0.0; //ft重叠部分前的计算的次数,ht重叠部分后计算的次数
int before = 0, behind = 0; //before重叠部分前的值,behind重叠部分后的值
//before
for (int k = i - r; j - r - 1 >= 0 && k <= i + r; k++)
{
if (k >= 0&&k<n) //很重要!!!!表明只在A矩阵以内的值才计算
{
before += A[k][j - r - 1];
ft += 1.0;
}
}
//behind
for (int k = i - r; j + r < n && k <= i + r; k++)
{
if (k >= 0&&k<n)
{
behind += A[k][j + r];
ht += 1.0;
}
}
temp = temp + pro[i][j - 1] - before + behind; //紫色=橙色-绿色+粉色
times = times - ft + ht;
pro[i][j] = temp;
}
if (temp / times <= t)
{
ans += 1;
//pp[i][j] = temp / times;
}
temp = 0;
}
times = 0.0;
}
cout << ans;
return 0;
}
核心思路:
如图所示:在矩阵A数组中,橙色框住的是A(0)(2)所需计算的值的范围,而紫色圈住的是A(0)(3),其中间有重复值,为了节省计算量,将前者的计算量存储在pro[]数组中,所以在计算紫色数组和时只需要将绿色的部分剪掉,再加上粉色的部分。
紫色=橙色-绿色+粉色;
这个公式适用于所有值(除第一列以外,因为该公式依赖于同一行的前一个pro数组中的内容,因此需要单独计算第一列)
与君共努力!
改进了一下
#include <iostream>
using namespace std;
int main()
{
std::ios::sync_with_stdio(false);
int n, L, r, t, ans = 0, temp = 0;
double times = 0.0;
cin >> n >> L >> r >> t;
int A[n][n] = {0};
int pro[n][n];
double pp[n][n] = {0.0};
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> A[i][j];
pro[i][j] = 0;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
int ti, tj;
ti = i - r;
tj = j - r;
if (ti < 0)
ti = 0;
if (tj < 0)
tj = 0;
if (j == 0)
{
for (int x = ti; x >= 0 && x - i <= r && x < n; x++)
{
for (int y = tj; y >= 0 && y - j <= r && y < n; y++)
{
temp += A[x][y];
times += 1.0;
}
}
}
else
{
double ft = 0.0, ht = 0.0;
int before = 0, behind = 0;
for (int k = ti; k < n && k <= i + r; k++)
{
if (j - r - 1 >= 0)
{
before += A[k][j - r - 1];
ft += 1.0;
}
if (j + r < n)
{
behind += A[k][j + r];
ht += 1.0;
}
}
temp = temp + pro[i][j - 1] - before + behind;
times = times - ft + ht;
}
pro[i][j] = temp;
if (temp / times <= t)
{
ans += 1;
pp[i][j] = temp / times;
}
temp = 0;
}
times = 0.0;
}
cout << ans;
return 0;
}