题目
解答
暴力枚举 70分
多个for循环嵌套(O(n^2 · 4r^2)
),30%样例超时
遍历时注意不要数组访问越界!
#include <iostream>
using namespace std;
int pic[601][601];
int counter = 0;
int main(){
int n,L,r,t;
cin>>n>>L>>r>>t;
//最多是(2r+1)^2,但是边界上的点取不到最多,求平均值时要统计个数
//int N = (2*r+1)*(2*r+1);
for(int i = 0; i < n;i++){
for(int j = 0; j < n;j++){
cin >> pic[i][j];
}
}
for(int i = 0; i < n;i++){
for(int j = 0; j < n;j++){
//Aij邻域元素求和
//max,min防止访问越界
int sum = 0;
int Xstart = max(0,i-r);
int Ystart = max(0,j-r);
//这里是n-1,下面是<=
int Xend = min(n-1,i+r);
int Yend = min(n-1,j+r);
int N = 0;
for(int x = Xstart;x <= Xend;x++){
for(int y = Ystart;y <= Yend;y++){
sum = sum + pic[x][y];
N++;
}
}
if(sum <= t*N){ //同×N,变除为乘(sum/N <= t)
counter++;
}
}
}
cout<<counter;
return 0;
}
二维前缀和 100分
空间换时间
#include <iostream>
using namespace std;
int pic[605][605];
int sum[605][605];
int counter = 0;
int main(){
int n,L,r,t;
cin>>n>>L>>r>>t;
for(int i = 1; i <= n;i++){
for(int j = 1; j <= n;j++){
cin >> pic[i][j];
//初始化二维前缀和数组sum[i][j]
sum[i][j] = pic[i][j] + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1];
}
}
for(int i = 1; i <= n;i++){
for(int j = 1; j <= n;j++){
//Aij邻域元素求和
int Xstart = max(1,i-r);
int Ystart = max(1,j-r);
int Xend = min(n,i+r);
int Yend = min(n,j+r);
//(Xstart,Ystart)到(Xend,Yend)区域的元素和
int total = sum[Xend][Yend] - sum[Xend][Ystart-1] - sum[Xstart-1][Yend] + sum[Xstart-1][Ystart-1];
if(total <= t*(Xend-Xstart+1)*(Yend-Ystart+1)){
counter++;
}
}
}
cout<<counter;
return 0;
}