2021-08-08 CFF-CSP 邻域均值 C语言实现
前言
本次实验所用设备为微软Surface pro4
,操作系统为windows10
。
注意事项
(1)CFF-CSP考试提交一定要使用C++编译环境 。
(2)本题主要考察前缀和来求取子区间的值 。
(3)一般CCF-CSP第二题会要求时间复杂度要为O(n)级别。
实验题目
实现代码如下
1、邻域均值暴力破解版 。
#include<stdio.h>
int main()
{
//申请变量
double L,r,t,sum,result,count;
int n,count1;
//初始化数据
scanf("%d",&n);
scanf("%lf",&L);
scanf("%lf",&r);
scanf("%lf",&t);
double A[n][n];
count1 = 0;
for(int i = 0;i < n;i++)
{
for(int j = 0;j < n;j++)
{
scanf("%lf",&A[i][j]);
}
}
//对每一个数的邻域进行测试
for(int i = 0;i < n;i++)
{
for(int j = 0;j < n;j++)
{
sum = 0.0; //对总数进行整合的初始化
count = 0.0; //对计数器进行初始化
//对本身这一行以及左边的数据进行加
for(int k = 0;k <= r;k++)
{
//对左上方的数据进行加
for(int g = 0;g <= r;g++)
{
if(i-k >= 0 && j-g >= 0)
{
//printf("%d %d",i-k,j-g);
sum += A[i-k][j-g];
//printf("%0.lf ",A[i-k][j-g]);
count++;
}
}
//对左下方的数据进行加
for(int g = 1;g <= r;g++)
{
if(i-k >= 0 && j+g < n)
{
sum += A[i-k][j+g];
//printf("%0.lf ",A[i-k][j+g]);
count++;
}
}
}
//对除本身这一行以外的右边的数据进行加
for(int k = 1;k <= r;k++)
{
//对左上方的数据进行加
for(int g = 0;g <= r;g++)
{
if(i+k < n && j-g >= 0)
{
sum += A[i+k][j-g];
//printf("%0.lf ",A[i+k][j-g]);
count++;
}
}
//对左下方的数据进行加
for(int g = 1;g <= r;g++)
{
if(i+k < n && j+g < n)
{
sum += A[i+k][j+g];
//printf("%0.lf ",A[i+k][j+g]);
count++;
}
}
}
//printf("\n");
//printf("%.0lf %0.lf\n",sum ,count);
//对最后的数据进行整合处理
//sum = sum-A[i][j];
result = sum/count;
if(result <= t)
{
//printf("%.0lf%d%d ",A[i][j],i,j);
count1++;
}
}
}
//对最后结果进行输出
printf("%d",count1);
return 0;
}
2、邻域均值算法处理版 。
#include<iostream>
#include<cstring>
using namespace std;
int dp[2000][2000],map[2000][2000];
int main()
{
int n,L,r,t;
scanf("%d%d%d%d",&n,&L,&r,&t); //输入数据
int i,j;
memset(dp,0,sizeof(dp)); //对二维数组进行初始化,全部初始化为0
//输入的同时完成二维前缀和的求取
for(i = 1; i <= n;i++)
{
for(j = 1;j <= n;j++)
{
scanf("%d",&map[i][j]);
dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1] + map[i][j];
}
}
//循环统计小于等阈值的区域个数
int count = 0;
int x1,x2,y1,y2;
for(i = 1;i <= n;i++)
{
for(j = 1;j <= n;j++)
{
double sum;
double sum_number;
double t_compare;
//确定要求的子区间的四个端点
x1 = i-r;
y1 = j-r;
x2 = i+r;
y2 = j+r;
if(x1 < 1)
{
x1 = 1;
}
if(y1 < 1)
{
y1 = 1;
}
if(x2 > n)
{
x2 = n;
}
if(y2 > n)
{
y2 = n;
}
//用前缀和进行子区间的计算
sum_number = (x2 - x1 + 1) * (y2 - y1 + 1);
sum = (dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1]) / sum_number;
//printf("sum_number=%lf ",sum_number);
//printf("sum=%lf ",sum);
t_compare = (double) t;
//printf("t_compare=%lf\n",t_compare);
if(sum <= t_compare)
{
count++;
}
}
}
printf("%d",count);
}