CSP201912-2-回收站选址题目解析-Java ,

时间:2022-07-28
本文章向大家介绍CSP201912-2-回收站选址题目解析-Java ,,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

这道题虽然是第二题,感觉有第三题的难度了。

做题注意点

1.会想要开一个很大的二维数组,比如a[1000000000][1000000000],比如1.0 就用a[1][0]=1,这样赋值的时候内存就会爆掉,所以不可行。需要换一种表示方式a[n][2],表示1.0就用a[n][0]=1 和a[n][1]=0;

2.因为需要判断所有的数字是否是回收站地址,所以需要一个大的for循环遍历所有数字。

3.通过如下代码判断上下左右斜对角是否有数字,然后对相关变量进行加减。

  if (point[i][0] == point[j][0] && point[i][1] - 1 == point[j][1]) {
                    f++;
                }

4.对坐标进行排序,x优先,y其次。先判断x,如果x相同判断y,从小到大。

    public static void sort(int[][] point, int n) { //从小到大排序
        int[] temp;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (point[i][0] > point[j][0]) { //第一个if用来排序x坐标,从小打到
                    temp = point[i];
                    point[i] = point[j];
                    point[j] = temp;
                } else if (point[i][0] == point[j][0] && point[i][1] > point[j][1]) { //第二个if用来排序对于x坐标相同的但是y不同的,从小到大
                    temp = point[i];
                    point[i] = point[j];
                    point[j] = temp;
                }
            }
        }
    }

代码展示

分开判断写法

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();
        int[][] point = new int[n][2];  //二维数组表示xy坐标
        int[] count = new int[5];  //五个分别表示回收站得分
        sc.nextLine();
        for (int i = 0; i < n; i++) {
            String[] strings = sc.nextLine().split(" ");
            point[i][0] = Integer.valueOf(strings[0]);
            point[i][1] = Integer.valueOf(strings[1]);
        }

        sort(point, n); //因为是随机输入,为了之后更方便设计算法,先排序


        for (int i = 0; i < n; i++) {//一个大循环遍历所有的数字
            int c = 0;
            int f = 0;
            for (int j = i - 1; j >= 0 && point[i][0] - 1 <= point[j][0]; j--) { //这个循环因为只需要比较i左边(比i小的)的坐标,所以本循环判断比i小的数字。从i开始
                // j比i倒退一个坐标,point[i][0] - 1 <= point[j][0]表示只用比较i旁边四个数字,例如i以1.1为例,[i][0]等于1,所以[i][0]-1=0,这时候j从1.0开始并且递减
                //1.0的x是1也就是[j][0]的值,所以当1.0递减的时候要大于刚才[i][0]-1=0,所以1.0、0.2、0.1、0.0都会涉及到,这样的方式可以限制周围的数字。
                if (point[i][0] == point[j][0] && point[i][1] - 1 == point[j][1]) {  //这里表示x坐标相等 y坐标相差一个的,所以代表了在i下面的坐标,如果有的话就会相等,f++代表下面有坐标。
                    f++;
                }
                if (point[i][1] == point[j][1] && point[i][0] - 1 == point[j][0]) { //和上面同理
                    f++;
                }
                if (point[i][0] - 1 == point[j][0] && point[i][1] + 1 == point[j][1]) { //这里代表i左上角的坐标,如果有的话得分c++
                    c++;
                }
                if (point[i][0] - 1 == point[j][0] && point[i][1] - 1 == point[j][1]) {
                    c++;
                }
            }



            for (int j = i + 1; j < n && point[i][0] + 1 >= point[j][0]; j++) { //本循环判断比i大的数字,比较i右边的坐标
                if (point[i][0] == point[j][0] && point[i][1] + 1 == point[j][1]) {//同理
                    f++;
                }
                if (point[i][0] == point[j][0] - 1 && point[i][1] == point[j][1]) {
                    f++;
                }
                if (point[i][0] == point[j][0] - 1 && point[i][1] == point[j][1] - 1) {
                    c++;
                }
                if (point[i][0] == point[j][0] - 1 && point[i][1] == point[j][1] + 1) {
                    c++;
                }
            }


            if (f == 4 && c >= 0) {
                count[c]++;  //对于上下左右都有的f==4,c表示得分

            }
        }
        for (int k = 0; k < 5; k++) {
            System.out.println(count[k]);
        }


    }

    public static void sort(int[][] point, int n) { //从小到大排序
        int[] temp;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (point[i][0] > point[j][0]) { //第一个if用来排序x坐标,从小打到
                    temp = point[i];
                    point[i] = point[j];
                    point[j] = temp;
                } else if (point[i][0] == point[j][0] && point[i][1] > point[j][1]) { //第二个if用来排序对于x坐标相同的但是y不同的,从小到大
                    temp = point[i];
                    point[i] = point[j];
                    point[j] = temp;
                }
            }
        }
    }
}

合并判断(无脑遍历)写法:

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();
        int[][] point = new int[n][2];  //二维数组表示xy坐标
        int[] count = new int[5];  //五个分别表示回收站得分
        sc.nextLine();
        for (int i = 0; i < n; i++) {
            String[] strings = sc.nextLine().split(" ");
            point[i][0] = Integer.valueOf(strings[0]);
            point[i][1] = Integer.valueOf(strings[1]);
        }

        sort(point, n); //因为是随机输入,为了之后更方便设计算法,先排序


        for (int i = 0; i < n; i++) {//一个大循环遍历所有的数字
            int c = 0;
            int f = 0;
            for (int j = 0; j<n;j++) { 
                if (point[i][0] == point[j][0] && point[i][1] - 1 == point[j][1]) {  //这里表示x坐标相等 y坐标相差一个的,所以代表了在i下面的坐标,如果有的话就会相等,f++代表下面有坐标。
                    f++;
                }
                if (point[i][1] == point[j][1] && point[i][0] - 1 == point[j][0]) { //和上面同理
                    f++;
                }
                if (point[i][0] - 1 == point[j][0] && point[i][1] + 1 == point[j][1]) { //这里代表i左上角的坐标,如果有的话得分c++
                    c++;
                }
                if (point[i][0] - 1 == point[j][0] && point[i][1] - 1 == point[j][1]) {
                    c++;
                }
                if (point[i][0] == point[j][0] && point[i][1] + 1 == point[j][1]) {//同理
                    f++;
                }
                if (point[i][0] == point[j][0] - 1 && point[i][1] == point[j][1]) {
                    f++;
                }
                if (point[i][0] == point[j][0] - 1 && point[i][1] == point[j][1] - 1) {
                    c++;
                }
                if (point[i][0] == point[j][0] - 1 && point[i][1] == point[j][1] + 1) {
                    c++;
                }
            }
            


            if (f == 4 && c >= 0) {
                count[c]++;  //对于上下左右都有的f==4,c表示得分

            }
        }
        for (int k = 0; k < 5; k++) {
            System.out.println(count[k]);
        }


    }

    public static void sort(int[][] point, int n) { //从小到大排序
        int[] temp;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (point[i][0] > point[j][0]) { //第一个if用来排序x坐标,从小打到
                    temp = point[i];
                    point[i] = point[j];
                    point[j] = temp;
                } else if (point[i][0] == point[j][0] && point[i][1] > point[j][1]) { //第二个if用来排序对于x坐标相同的但是y不同的,从小到大
                    temp = point[i];
                    point[i] = point[j];
                    point[j] = temp;
                }
            }
        }
    }
}