CSP邻域均值(Java)

首先常规解法就是暴力,遍历每个点,然后算周围一圈,这样可以拿下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;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,我无法确定您具体想了解什么关于CSP出行计划Java方面的内容。但是,我可以为您提供一些关于CSP出行计划和Java的基本信息。 CSP出行计划是一个基于云计算的智能交通出行服务平台,它可以为用户提供出行规划、路线推荐、实时路况、公交查询等服务。而Java是一种广泛使用的编程语言,它可以用于开发各种类型的应用程序,包括Web应用程序、桌面应用程序、移动应用程序等。 如果您想了解如何使用Java开发CSP出行计划相关的应用程序,您可以参考以下步骤: 1.了解CSP出行计划的API接口文档,确定需要使用哪些API接口。 2.使用Java编写代码,调用CSP出行计划的API接口,获取所需的数据。 3.根据获取的数据,进行相应的处理和展示,以实现所需的功能。 下面是一个使用Java调用CSP出行计划API接口获取公交查询结果的示例代码: ```java import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; public class BusQuery { public static void main(String[] args) { String appkey = "your_appkey";//你的appkey String city = "北京";//城市名 String bus = "特8";//公交线路名 String url = "http://api.csp.cn/bus/line?appkey=" + appkey + "&city=" + URLEncoder.encode(city) + "&bus=" + URLEncoder.encode(bus); String result = ""; try { URL realUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection(); conn.setRequestMethod("GET"); conn.connect(); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); String line; while ((line = in.readLine()) != null) { result += line; } in.close(); } catch (Exception e) { e.printStackTrace(); } System.out.println(result); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值