首先常规解法就是暴力,遍历每个点,然后算周围一圈,这样可以拿下70分,这里我就不细说暴力了,我主要说说说如何优化的问题。
当你暴力时你就会发现每个元素会重复计算多次,我们的目标就减少这种重复的计算。之前的暴力就好比你每次给数据按上一个框进行分别计算,现在我们想的是把框固定下来,就像一个毛毛虫一样前面吃一列后面出一列,这样每个点的计算量就变成了4r+2,这样一列一列的向前推动。
还有一点小技巧就是数组的起点我设的是【100】【100】
总大小是【800】【800】
然后初始化的时候没用的地方用T值
填充,这样就不用考虑边界问题了。
下面就是具体的代码
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
//Scanner in =new Scanner(System.in);
read in =new read();
PrintWriter pw =new PrintWriter(System.out);
int n=in.nextInt();
int l=in.nextInt();
int r=in.nextInt();
int t=in.nextInt();
int arr[][]=new int[800][800];
//这部分就是初始化
for (int i=0;i<800;i++){
for (int j=0;j<800;j++){
//这个判断是用来判断没用的部分,然后用t填充,这样以后计算就不会产生影响
if (i<100||j<100||i>=100+n||j>=100+n)
arr[i][j]=t;
else
arr[i][j]=in.nextInt();
}
}
//用来记录这个框中总和的最小值,小于等于count的就是暗点
int count=(2*r+1)*(2*r+1)*t;
int[][] map=new int[n][n];//用来记录每个门框的大小方便推到
int sum=0;
int ru=0;//用来记录最后答案个数
//这里是先算个头map【0】【0】
for (int i=100-r;i<=100+r;i++){
for (int j=100-r;j<=100+r;j++){
sum+=arr[i][j];
}
}
map[0][0]=sum;
if (sum<=count)ru++;
//这是根据00,推导map的第一行,a是记录新增的一列,b是去掉的一列
for (int j=101;j<100+n;j++){
int a = 0,b=0;
for (int i=100-r;i<=100+r;i++)
a+=arr[i][j+r];
for (int i=100-r;i<=100+r;i++)
b+=arr[i][j-r-1];
map[0][j-100]=map[0][j-101]+a-b;
if (map[0][j-100]<=count)ru++;
}
//上面一步已经把每列都开了一个头,这样我们就可以全部推导了,一列一列竖着来,从上往下
for (int j=100;j<100+n;j++){
for (int i=101;i<100+n;i++){
int a=0,b=0;
for (int jj=j-r;jj<=j+r;jj++){
a+=arr[i+r][jj];
}
for (int jj=j-r;jj<=j+r;jj++){
b+=arr[i-r-1][jj];
}
map[i-100][j-100]=map[i-101][j-100]+a-b;
if (map[i-100][j-100]<=count)ru++;
}
}
pw.println(ru);
pw.flush();
//这个关键就是把握每次遍历的边界,建议动手画画不容易乱,然后还不懂可以Debug一下观察一下map数组的运算过程
//如果谁有更好的办法请不吝赐教。
}
}
//大输入输出都要用,懂得都懂
class read{
StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int nextInt() throws IOException {
st.nextToken();
return (int)st.nval;
}
long nextLong() throws IOException {
st.nextToken();
return (long)st.nval;
}
String next() throws IOException {
st.nextToken();
return st.sval;
}
}