zoukankan      html  css  js  c++  java
  • CCF签到汇总(JAVA版本,2013-12~2018-12)

    CCF签到题,没有提到分数的题目都是100分,不然会额外提出,样例输入都单独文本复制粘贴了,这样你们测试的时候很方便粘贴用例,不用自己手敲,都是一些签到题。但有好的基础,会多的数据结构,好的数学思想,那么这些都是一些很简单的问题。因为java版本不多,所以仅供参考,以下代码的思路都很简单,很多都直接通过题目面向过程,有更好的想法,或者你我有些题没有满分的改进方式都可以交流。

    CCF300分的线,1、2题需要拿满,最低也要190,第三题是理解题,很多时候考你的语文能力更多,第四题是规律性更强的题,涉及图论算法众多(最小生成树3题,通信网络,最优灌溉,数据中心,地铁修建)(最短路径4题,最优匹配,无线网络,交通规划,游戏)(欧拉图,强连通分支,最长路径也都考过),还有正则匹配的题(5题url映射,json查询,markdown,模板生成系统,字符中匹配),总而言之一句话,第4题规律性很强。你只需要1、2题拿满,第4题拿90,第五题和第三题通过理解之后,暴力得分,就能稳300分以上,不排除某年的题会难、杂,或者当年当月你不在巅峰,那就下一次再考,上面列举的题型出现的频率极高,针对1、2、4刷题性价比是最高的。

    下面只提供了第一题和第二题,因为在线测试对java语言不太友好,导致我的3、4题分数参差不齐,所以没有提供代码,网上有众多优秀的博客,输入试题编号和名称即可找到,看看思路,自己再写一遍,算法之路,任重道远。(数学很重要,数学是编程的降维武器)


    试题编号:201312-1

    试题名称:出现次数最多的数

    image

    样例输入

    6
          10 1 10 20 30 20

    样例输出

    10

    思路:解决方法有很多,要么空间够大开够,用下标去加加计数,或者用hashset一直塞,重复会返回default,然后default就对应加加,用indexof找,唯一值,还可以用一个数组,在插入时注意排序,因为需要输出最小值,插入时就排好序,重复的就加加次数,总之方法很多。

    import java.util.Scanner;
    
    public class CCF201312_1 {
        public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            int n=sc.nextInt();
            int[] space=new int[n];
            for(int i=0;i<n;i++) {
                space[i]=sc.nextInt();
            }
            int[] flag=new int[10000];
            for(int i=0;i<n;i++) {
                flag[space[i]]++;
            }
            int max=0;
            int index=0;
            int finded=0;
            for(int i=0;i<10000;i++) {
                if(flag[i]!=0) {
                    finded=finded+flag[i];
                }
                if(flag[i]>max) {
                    max=flag[i];
                    index=i;
                }
                if(finded==n) {
                    break;
                }
            }
            System.out.println(index);
        }
    }

    试题编号:201312-2

    试题名称:ISBN号码

    image

    样例输入

    0-670-82162-0

    样例输出

    0-670-82162-4

    思路:问题描述中已经有具体步骤了,对于格式统一,下标固定的问题,基本数据结构掌握就可以解决。

    import java.util.Scanner;
    
    public class CCF201312_2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            String sourse = sc.nextLine();
            int ret = 1 * (sourse.charAt(0) - '0') + 2 * (sourse.charAt(2) - '0') + 3 * (sourse.charAt(3) - '0')
                    + 4 * (sourse.charAt(4) - '0') + 5 * (sourse.charAt(6) - '0') + 6 * (sourse.charAt(7) - '0')
                    + 7 * (sourse.charAt(8) - '0') + 8 * (sourse.charAt(9) - '0') + 9 * (sourse.charAt(10) - '0');
            ret = ret % 11;
            if (sourse.charAt(12) == 'X') {// 如果默认为X
                if (ret == 10) {// 匹配对
                    System.out.print("Right");
                    return;
                } else {// 不匹配
                    for (int i = 0; i < sourse.length() - 1; i++) {
                        System.out.print(sourse.charAt(i));
                    }
                    System.out.print(ret);
                }
            } else {//默认不是X
                if ((sourse.charAt(12) - '0') == ret) {
                    System.out.print("Right");
                    return;
                }
                if (ret == 10) {
                    for (int i = 0; i < sourse.length() - 1; i++) {
                        System.out.print(sourse.charAt(i));
                    }
                    System.out.print("X");
                    return;
                } else {
                    for (int i = 0; i < sourse.length() - 1; i++) {
                        System.out.print(sourse.charAt(i));
                    }
                    System.out.print(ret);
                }
            }
        }
    }

    试题编号:201403-1

    试题名称:相反数

    image

    样例输入

    5
          1 2 3 -1 -2

    样例输出

    2

    思路:给了范围,不会超过一千,用二维数组,正负分开在二维数组上加加,然后判断有多少对即可,用finded去记录找到的数目,可以提前退出循环,提高速度。

    import java.util.Scanner;
    
    public class CCF201403_1 {
        public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            int N=sc.nextInt();
            int[] sourse=new int[N];
            int[][] flag=new int[1000][2];
            for(int i=0;i<N;i++) {
                sourse[i]=sc.nextInt();
                if(sourse[i]>0) {
                    flag[sourse[i]][1]++;
                }
                else {
                    flag[-1*sourse[i]][0]++;
                }
            }
            int finded=0;
            int count=0;
            for(int i=0;i<1000;i++) {
                if(flag[i][0]>0||flag[i][1]>0) {
                    finded+=flag[i][0]+flag[i][1];
                }
                if((flag[i][0]>flag[i][1])&&(flag[i][1]>0)) {
                    count+=flag[i][1];                
                }
                if((flag[i][1]>flag[i][0])&&(flag[i][0]>0)) {
                    count+=flag[i][0];
                }
                if((flag[i][1]==flag[i][0])&&flag[i][1]>0) {
                    count+=flag[i][0];
                }
                if(finded==N) {
                    break;
                }
            }
            System.out.println(count);
        }
    }

    试题编号:201403-2

    试题名称:窗口

    image

    样例输入

    3 4
          0 0 4 4
          1 1 5 5
          2 2 6 6
          1 1
          0 0
          4 4
          0 5

    样例输出

    2
          1
          1
          IGNORED

    样例说明

      第一次点击的位置同时属于第 1 和第 2 个窗口,但是由于第 2 个窗口在上面,它被选择并且被置于顶层。
           第二次点击的位置只属于第 1 个窗口,因此该次点击选择了此窗口并将其置于顶层。现在的三个窗口的层次关系与初始状态恰好相反了。
           第三次点击的位置同时属于三个窗口的范围,但是由于现在第 1 个窗口处于顶层,它被选择。
           最后点击的 (0, 5) 不属于任何窗口。

    思路:这题有点意思,但是题目中告诉你窗口是自下向上给出,而窗口在上方的又具有更高的优先级,所以用数组存取每一层窗口的坐标,下标越高的窗口优先级就越高,从后往前遍历,看chick的点是否在当前层之内,如果在就输出,并且用newone函数去把当前窗口的级别调整到最高,也就是向数组的最后部推,这样优先级即为最高,实现比较器会比较方便交换,这里直接用temp值交换了。

    import java.util.Scanner;
    
    public class CCF201403_2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int N = sc.nextInt();
            int M = sc.nextInt();
            int[][] Sourse = new int[N][5];
            for (int i = 0; i < N; i++) {
                Sourse[i][0] = sc.nextInt();
                Sourse[i][1] = sc.nextInt();
                Sourse[i][2] = sc.nextInt();
                Sourse[i][3] = sc.nextInt();
                Sourse[i][4]=i+1;
            }
            int[][] chick = new int[M][2];
            for (int i = 0; i < M; i++) {
                chick[i][0] = sc.nextInt();
                chick[i][1] = sc.nextInt();
            }
            int key = 0;
            for (int i = 0; i < M; i++) {
                int j;
                for (j = N - 1; j >= 0; j--) {
                    if ((Sourse[j][0] <= chick[i][0]) && (chick[i][0] <= Sourse[j][2]) && (Sourse[j][1] <= chick[i][1])
                            && (chick[i][1] <= Sourse[j][3])) {
                        System.out.println(Sourse[j][4]);
                        Sourse = newOne(Sourse, j);
                        break;
                    }
                }
                if (j == -1) {
                    System.out.println("IGNORED");
                }
            }
        }
    
        public static int[][] newOne(int[][] Sourse, int key) {
            int n = Sourse.length - 1;
            int tempX1 = Sourse[key][0];
            int tempY1 = Sourse[key][1];
            int tempX2 = Sourse[key][2];
            int tempY2 = Sourse[key][3];
            int tempIndex=Sourse[key][4];
            for (int i = key; i < n; i++) {
                Sourse[i][0] = Sourse[i + 1][0];
                Sourse[i][1] = Sourse[i + 1][1];
                Sourse[i][2] = Sourse[i + 1][2];
                Sourse[i][3] = Sourse[i + 1][3];
                Sourse[i][4] = Sourse[i + 1][4];
            }
            Sourse[n][0] = tempX1;
            Sourse[n][1] = tempY1;
            Sourse[n][2] = tempX2;
            Sourse[n][3] = tempY2;
            Sourse[n][4]=tempIndex;
            return Sourse;
        }
    }

    试题编号:201409-1

    试题名称:相邻数对

    image

    样例输入

    6
         10 2 6 3 7 8

    样例输出

    3

    样例说明

       值正好相差1的数对包括(2, 3), (6, 7), (7, 8)。

    评测用例规模与约定

       1<=n<=1000,给定的整数为不超过10000的非负整数。

    思路:因为数值最大为10000,但要考虑重复的情况,第一题一般对时间空间没有什么要求,用下标去加加计数,然后通过循环去获取相邻差为1的整数对,用finded去对找到的点进行计数提前退出,然后去找连续的重复值加到ret上即可。

    import java.util.Scanner;
    
    public class CCF201409_1 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int[] sourse = new int[n];
            int[] space = new int[10000];
            for (int i = 0; i < n; i++) {
                sourse[i] = sc.nextInt();
                space[sourse[i]]++;
            }
            int ret = 0;
            int finded = 0;
            for (int i = 0; i < 9999; i++) {
                if (space[i] > 0) {
                    finded += space[i];
                    if (space[i + 1] > 0) {
                        ret += space[i + 1];
                    }
                }
                if (finded == n) {
                    break;
                }
            }
            System.out.println(ret);
        }
    }

    试题编号:201409-2

    试题名称:画图

    image

    样例输入

    2
          1 1 4 4
          2 3 6 5

    样例输出

    15

    评测用例规模与约定

    1<=n<=100,0<=横坐标、纵坐标<=100。

    思路: 简单的遍历,涂色,网络上还有逆向思路的,去计算最大正方形,然后扣空,但不易操作,所以通过开辟空间使问题简单化

    import java.util.Scanner;
    
    public class CCF201409_2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int[][] space = new int[n][4];
            int minX = 100;
            int maxX = 0;
            int minY = 100;
            int maxY = 0;
            for (int i = 0; i < n; i++) {
                space[i][0] = sc.nextInt();
                if (space[i][0] < minX) {
                    minX = space[i][0];
                }
                space[i][1] = sc.nextInt();
                if (space[i][1] < minY) {
                    minY = space[i][1];
                }
                space[i][2] = sc.nextInt();
                if (space[i][2] > maxX) {
                    maxX = space[i][2];
                }
                space[i][3] = sc.nextInt();
                if (space[i][3] > maxY) {
                    maxY = space[i][3];
                }
            }
            int[][] color = new int[maxX - minX][maxY - minY];
            for (int i = 0; i < n; i++) {
                for (int j = space[i][0] - minX; j < space[i][2] - minX; j++) {
                    for (int k = space[i][1] - minY; k < space[i][3] - minY; k++) {
                        color[j][k]++;
                    }
                }
            }
            int ret = 0;
            for (int i = 0; i < maxX - minX; i++) {
                for (int j = 0; j < maxY - minY; j++) {
                    if (color[i][j] > 0) {
                        ret++;
                    }
                }
            }
            System.out.println(ret);
        }
    }

    试题编号:201412-1

    试题名称:门禁系统

    image

    样例输入

    5
          1 2 1 1 3

    样例输出

    1 1 2 3 1

    评测用例规模与约定

       1≤n≤1,000,读者的编号为不超过n的正整数。

    思路:很水的题,直接边读边输出就行了。

    import java.util.Scanner;
    public class CCF201412_1 {
        public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            int n=sc.nextInt();
            int[] array=new int[1000];
            for(int i=0;i<n;i++) {
                System.out.println(++array[sc.nextInt()]);
            }
        }
    }

    试题编号:201412-2

    试题名称:Z字形扫描

    image

    样例输入

    4
          1 5 3 9
          3 7 5 6
          9 4 6 4
          7 3 1 3

    样例输出

    1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3

    评测用例规模与约定

      1≤n≤500,矩阵元素为不超过1000的正整数。

    思路:也是一道比较有意思的题,但是找到规律之后也很简单,首先分奇偶,然后把拐角的点和直线的点都写出来,就发现出现的情况是一定对称的,不论奇偶都是对称的,拐点是周期性循环变化,拐弯之后的直线周期性增加,当到对角线时操作最长为y,不理解的同学可以把过程的点都写出来,然后在这些点之间,把x++,或y++的变化过程标上去,就一目了然了。最后不要忘记特殊情况的处理。还理解不了的可以结合着图,并且通过debug模式去一步一步的推算,规律题。

    import java.util.Scanner;
    
    public class CCF201412_2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int[][] Z = new int[n][n];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    Z[i][j] = sc.nextInt();
                }
            }
            if (n == 1) {
                System.out.print(Z[0][0]);
                return;
            }
            if (n == 2) {
                System.out.print(Z[0][0] + " " + Z[0][1] + " " + Z[1][0] + " " + Z[1][1]);
                return;
            }
            int x = 0;
            int y = 0;
            int flag = 1;
            int choose = 1;
            System.out.print(Z[x][y] + " ");
            choose = -1;
            while (flag != n) {
                if (choose == -1) {
                    System.out.print(Z[x][++y] + " ");
                    for (int i = 0; i < flag; i++) {
                        System.out.print(Z[++x][--y] + " ");
                    }
                    choose = 1;
                } else {
                    System.out.print(Z[++x][y] + " ");
                    for (int i = 0; i < flag; i++) {
                        System.out.print(Z[--x][++y] + " ");
                    }
                    choose = -1;
                }
                flag++;
            }
            flag--;
            flag--;
            choose = choose * -1;
            while (flag != 0) {
                if (choose == -1) {
                    System.out.print(Z[x][++y] + " ");
                    for (int i = 0; i < flag; i++) {
                        System.out.print(Z[--x][++y] + " ");
                    }
                    choose = 1;
                } else {
                    System.out.print(Z[++x][y] + " ");
                    for (int i = 0; i < flag; i++) {
                        System.out.print(Z[++x][--y] + " ");
                    }
                    choose = -1;
                }
                flag--;
            }
            System.out.print(Z[x][++y]);
        }
    }

    试题编号:201503-1

    试题名称:图像旋转

    image

    样例输入

    2 3
          1 5 3
          3 2 4

    样例输出

    3 4
          5 2
          1 3

    评测用例规模与约定

      1 ≤ n, m ≤ 1,000,矩阵中的数都是不超过1000的非负整数。

    思路:存进去,读出来就行,就是一个相对坐标转化。这代码跑的时候,一次过,一次超时的。。。神奇的在线测试。

    import java.util.Scanner;
    
    public class CCF201503_1 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int m = sc.nextInt();
            int n=sc.nextInt();
            int[][] ret=new int[n][m];
            for(int j=0;j<m;j++) {
                for(int i=n-1;i>=0;i--) {
                    ret[i][j]=sc.nextInt();
                }
            }
            for(int i=0;i<n;i++) {
                for(int j=0;j<m;j++) {
                    System.out.print(ret[i][j]+" ");
                }
                System.out.print("
    ");
            }
        }
    }

    试题编号:201503-2

    试题名称:数字排序

    image

    样例输入

    12
          5 2 3 3 1 3 4 2 5 2 3 5

    样例输出

    3 4
          2 3
          5 3
          1 1
          4 1

    评测用例规模与约定

      1 ≤ n ≤ 1000,给出的数都是不超过1000的非负整数。

    思路:简单题,别把自己绕进去就行,就一个排序,排序时注意出现次数一样多,先输出小的。用了冒泡排序。

    package CCF;
    
    import java.util.Arrays;
    import java.util.HashSet;
    import java.util.Scanner;
    
    public class CCF201503_2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int[] sourse = new int[n];
            HashSet hs = new HashSet();
            for (int i = 0; i < n; i++) {
                sourse[i] = sc.nextInt();
                hs.add(sourse[i]);
            }
            Arrays.sort(sourse);
            int sizes = hs.size();
            int[][] ret = new int[sizes][2];
            int flag = 0;
            for (int i = 0; i < n; i++) {
                if (i == 0) {
                    ret[flag][0] = sourse[i];
                    ret[flag][1]++;
                    continue;
                }
                if (sourse[i] == ret[flag][0]) {// 如果和前一个相等
                    ret[flag][1]++;
                } else {// 和前一个不相等
                    flag++;
                    ret[flag][0] = sourse[i];
                    ret[flag][1]++;
                }
            }
            int temp0 = 0;
            int temp1 = 0;
            for (int i = 0; i < sizes; i++) {
                for (int j = 0; j < sizes - 1 - i; j++) {
                    if (ret[j + 1][1] > ret[j][1]) {
                        temp0 = ret[j + 1][0];
                        temp1 = ret[j + 1][1];
                        ret[j + 1][0] = ret[j][0];
                        ret[j + 1][1] = ret[j][1];
                        ret[j][0] = temp0;
                        ret[j][1] = temp1;
                        continue;
                    }
                    if (ret[j + 1][1] == ret[j][1]) {
                        if (ret[j + 1][0] < ret[j][0]) {
                            temp0 = ret[j + 1][0];
                            temp1 = ret[j + 1][1];
                            ret[j + 1][0] = ret[j][0];
                            ret[j + 1][1] = ret[j][1];
                            ret[j][0] = temp0;
                            ret[j][1] = temp1;
                        }
                    }
                }
            }
            for (int i = 0; i < sizes; i++) {
                System.out.println(ret[i][0] + " " + ret[i][1]);
            }
        }
    }

    试题编号:201509-1

    试题名称:数列分段

    image

    样例输入

    8
          8 8 8 0 12 12 8 0

    样例输出

    5

    样例说明

      8 8 8是第一段,0是第二段,12 12是第三段,倒数第二个整数8是第四段,最后一个0是第五段。

    评测用例规模与约定

      1 ≤ n ≤ 1000,0 ≤ ai ≤ 1000。

    思路:就是边读边判断是否和前一个一样,如果一样不操作,不一样就加加。

    import java.util.Scanner;
    
    public class CCF201509_1 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            if (n == 1) {
                System.out.println(1);
            }
            int[] A = new int[n];
            int ret = 1;
            for (int i = 0; i < n; i++) {
                A[i] = sc.nextInt();
                if (i != 0) {// 除去第一个
                    if (A[i] != A[i - 1]) {
                        ret++;
                    }
                }
            }
            System.out.println(ret);
        }
    }

    试题编号:201509-2

    试题名称:日期计算

    image

    样例输入

    2015
          80

    样例输出

    3
          21

    样例输入

    2000
          40

    样例输出

    2
          9

    思路:人基本常识必须要有,剩下的就是简答操作了。

    import java.util.Scanner;
    
    public class CCF201509_2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int year=sc.nextInt();
            int d=sc.nextInt();
            int[] mounth=new int[] {31,0,31,30,31,30,31,31,30,31,30,31};
            if(((year%4==0)&&(year%100!=0))||(year%400==0)) {
                mounth[1]=29;
            }
            else {
                mounth[1]=28;
            }
            for(int i=0;i<12;i++) {
                if(d>mounth[i]) {
                    d-=mounth[i];
                }
                else {
                    System.out.println(i+1);
                    System.out.println(d);
                    return;
                }
            }
        }
    }

    试题编号:201512-1

    试题名称:数位之和

    image

    样例输入

    20151220

    样例输出

    13

    样例说明

      20151220的各位数字之和为2+0+1+5+1+2+2+0=13。

    评测用例规模与约定

      所有评测用例满足:0 ≤ n ≤ 1000000000。

    思路:charAt的标准用法之一,注意char转int即可。

    import java.util.Scanner;
    
    public class CCF201512_1 {
        public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            String sourse=sc.nextLine();
            int ret=0;
            for(int i=0;i<sourse.length();i++) {
                ret+=(sourse.charAt(i)-'0');
            }
            System.out.println(ret);
        }
    }

    试题编号:201512-2

    试题名称:消除类游戏

    image

    样例输入

    4 5
          2 2 3 1 2
          3 4 5 1 4
          2 3 2 1 3
          2 2 2 4 4

    样例输出

    2 2 3 0 2
          3 4 5 0 4
          2 3 2 0 3
          0 0 0 4 4

    样例说明

      棋盘中第4列的1和第4行的2可以被消除,其他的方格中的棋子均保留。

    样例输入

    4 5
          2 2 3 1 2
          3 1 1 1 1
          2 3 2 1 3
          2 2 3 3 3

    样例输出

    2 2 3 0 2
          3 0 0 0 0
          2 3 2 0 3
          2 2 0 0 0

    样例说明

      棋盘中所有的1以及最后一行的3可以被同时消除,其他的方格中的棋子均保留。

    评测用例规模与约定

      所有的评测用例满足:1 ≤ n, m ≤ 30。

    思路:横向遍历一次,纵向遍历一次,用二维数组对可以消除的置1,并且因为3连可消,下标也直接已知,可以简化一点循环。

    import java.util.Scanner;
    
    public class CCF201512_2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int m = sc.nextInt();
            int[][] ret = new int[n][m];
            int[][] sourse = new int[n][m];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    sourse[i][j] = sc.nextInt();
                }
            }
            int[] flag = new int[2];
            for (int i = 0; i < n; i++) {
                flag[0] = sourse[i][0];
                flag[1] = 1;
                for (int j = 1; j < m; j++) {
                    if (flag[0] == sourse[i][j]) {
                        flag[1]++;
                    } else {
                        flag[0] = sourse[i][j];
                        flag[1] = 1;
                    }
                    if (flag[1] >= 3) {
                        ret[i][j] = 1;
                        ret[i][j - 1] = 1;
                        ret[i][j - 2] = 1;
                    }
                }
            }
    
            for (int j = 0; j < m; j++) {
                flag[0] = sourse[0][j];
                flag[1] = 1;
                for (int i = 1; i < n; i++) {
                    if (flag[0] == sourse[i][j]) {
                        flag[1]++;
                    } else {
                        flag[0] = sourse[i][j];
                        flag[1] = 1;
                    }
                    if (flag[1] >= 3) {
                        ret[i][j] = 1;
                        ret[i - 1][j] = 1;
                        ret[i - 2][j] = 1;
                    }
                }
            }
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (ret[i][j] == 0) {
                        System.out.print(sourse[i][j] + " ");
                    } else {
                        System.out.print(0 + " ");
                    }
                }
                System.out.println();
            }
        }
    }

    试题编号:201604-1

    试题名称:折点计数

    image

    样例输入

    7
          5 4 1 2 3 6 4

    样例输出

    2

    评测用例规模与约定

      所有评测用例满足:1 ≤ n ≤ 1000,每天的销售量是不超过10000的非负整数。

    思路:用flag去记录前一组数据的斜率的正负,如果斜率正负变化,说明发生拐点。

    import java.util.Scanner;
    
    public class CCF201604_1 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            if (n == 1) {
                int mm = sc.nextInt();
                System.out.println(0);
                return;
            }
            if (n == 2) {
                int mm = sc.nextInt();
                int mmm = sc.nextInt();
                System.out.println(0);
                return;
            }
            int[] A = new int[n];
            int flag = 0;
            int temp = 0;
            int ret = 0;
            for (int i = 0; i < n; i++) {
                A[i] = sc.nextInt();
                if (i == 1) {
                    flag = ZhengOrFu(A[0], A[1]);
                }
                if (i != 0) {
                    temp = ZhengOrFu(A[i - 1], A[i]);
                    if (temp != flag) {
                        ret++;
                        flag = temp;
                    }
                }
            }
            System.out.println(ret);
        }
    
        public static int ZhengOrFu(int m, int n) {
            if ((n - m) >= 0) {
                return -1;
            } else {
                return 1;
            }
        }
    }

    试题编号:201604-2

    试题名称:俄罗斯方块

    image

    样例输入

    0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 1 0 0
          0 0 0 0 0 0 1 0 0 0
          0 0 0 0 0 0 1 0 0 0
          1 1 1 0 0 0 1 1 1 1
          0 0 0 0 1 0 0 0 0 0
          0 0 0 0
          0 1 1 1
          0 0 0 1
          0 0 0 0
          3

    样例输出

    0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 1 0 0
          0 0 0 0 0 0 1 0 0 0
          0 0 0 0 0 0 1 0 0 0
          1 1 1 1 1 1 1 1 1 1
          0 0 0 0 1 1 0 0 0 0

    思路:这道题我只有90分,因为游戏界面优先,可显示的部分是固定的,所以计算极端情况,额外上下开辟一定空间(4,一个方块的大小),然后计算最多可下落的距离,直接刷新过去就可以了,没有满分可能是没有考虑到一些特殊情况,不过思路可以参考,网上也有很多优秀的简短代码,我的思想比较简单,并且需要改进。

    import java.util.Scanner;
    
    public class CCF201604_2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int[][] sourse = new int[23][10];
            for (int i = 4; i < 19; i++) {
                for (int j = 0; j < 10; j++) {
                    sourse[i][j] = sc.nextInt();
                }
            }
            int[][] block = new int[4][4];
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    block[i][j] = sc.nextInt();
                }
            }
            int startIndex = sc.nextInt() - 1;
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    if (block[i][j] != 0) {
                        sourse[i][j + startIndex]++;
                    }
                }
            }
    
            int[] minBlock = new int[4];
            int[] minDepth = new int[4];
            for (int j = 0; j < 4; j++) {
                for (int i = 3; i >= 0; i--) {
                    if (block[i][j] == 0) {
                        minBlock[j]++;
                    } else {
                        break;
                    }
                }
            }
            for (int j = startIndex; j < startIndex + 4; j++) {
                for (int i = 4; i < 19; i++) {
                    if (sourse[i][j] == 0) {
                        minDepth[j - startIndex]++;
                    } else {
                        break;
                    }
                }
            }
            int min = 19;
            int index = 0;
            for (int i = 0; i < 4; i++) {
                if ((minBlock[i] + minDepth[i]) < min) {
                    min = minBlock[i] + minDepth[i];
                    index = i;
                }
            }
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    if (block[i][j] == 1) {
                        sourse[i + min][j + startIndex]++;
                    }
                }
            }
            Print(sourse);
        }
    
        public static void Print(int[][] sourse) {
            for (int i = 4; i < 19; i++) {
                for (int j = 0; j < 10; j++) {
                    System.out.print(sourse[i][j] + " ");
                }
                System.out.println();
            }
        }
    }

    试题编号:201609-1

    试题名称:最大波动

    image

    样例输入

    6
          2 5 5 7 3 5

    样例输出

    4

    样例说明

      第四天和第五天之间的波动最大,波动值为|3-7|=4。

    评测用例规模与约定

      对于所有评测用例,2 ≤ n ≤ 1000。股票每一天的价格为1到10000之间的整数。

    思路:边读数据,边计算差值,比较即可。

    import java.util.Scanner;
    
    public class CCF201609_1 {
        public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            int n=sc.nextInt();
            int[] A=new int[n];
            int max=0;
            for(int i=0;i<n;i++) {
                A[i]=sc.nextInt();
                if(i!=0) {
                    if(Math.abs((A[i]-A[i-1]))>max) {
                        max=Math.abs(A[i]-A[i-1]);
                    }
                }
            }
            System.out.println(max);
        }
    }

    试题编号:201609-2

    试题名称:火车购票

    image

    样例输入

    4
          2 5 4 2

    样例输出

    1 2
          6 7 8 9 10
          11 12 13 14
          3 4

    样例说明

      1) 购2张票,得到座位1、2。
         2) 购5张票,得到座位6至10。
       3) 购4张票,得到座位11至14。
      4) 购2张票,得到座位3、4。

    评测用例规模与约定

      对于所有评测用例,1 ≤ n ≤ 100,所有购票数量之和不超过100。

    思路:这道题也只拿了90分,思想很简单,就是遍历每一个数组,去匹配剩余的空间,如果够就一口气插入,下标直接更新,数组当前层的大小(length)就是下一次需要插入的坐标,思路很简单,但是只有90分,特殊情况考虑不够,历年的一二题都比较简单,但是需要够细致,考虑完所有的特殊、极限情况。

    import java.util.Scanner;
    
    public class CCF201609_2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int[][] space = new int[20][5];
            int[] sourse = new int[n];
            for (int i = 0; i < n; i++) {
                int need = sc.nextInt();
                sourse[i] = need;
                int flag = 0;
                for (int j = 0; j < 20; j++) {// 遍历每一排看空间
                    if (L(space, j) >= need) {
                        for (int k = 0; k < need; k++) {
                            space[j][5 - L(space, j)]++;
                            System.out.print((j * 5 + 5 - L(space, j)) + " ");
                        }
                        flag = 1;
                        break;// 跳出循环去接收下一个数据
                    }
                }
                if (flag == 0) {
                    int temp = need;
                    for (int j = 0; j < 20; j++) {
                        if (temp == 0) {
                            break;
                        }
                        if (L(space, j) > 0) {
                            for (int k = 0; k < need; k++) {
                                space[j][5 - L(space, j)]++;
                                System.out.print((j * 5 + k + 1) + " ");
                                temp--;
                            }
                        }
                    }
                }
                System.out.println();
            }
        }
    
        public static int L(int[][] space, int index) {
            int ret = 0;
            for (int i = 0; i < 5; i++) {
                if (space[index][i] == 0) {
                    ret++;
                }
            }
            return ret;
        }
    }

    试题编号:201612-1

    试题名称:中间数

    image

    样例输入

    6
          2 6 5 6 3 5

    样例输出

    5

    样例说明

      比5小的数有2个,比5大的数也有2个。

    样例输入

    4
          3 4 6 7

    样例输出

    -1

    样例说明

      在序列中的4个数都不满足中间数的定义。

    样例输入

    5
          3 4 6 6 7

    样例输出

    -1

    样例说明

      在序列中的5个数都不满足中间数的定义。

    评测用例规模与约定

      对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ ai ≤ 1000。

    思路:还是喜欢前几年,用例给两个,并且给的用例面一半会比较广、不同。2种方式,都需要先排序,你要满足大于你的数等于小于你的数,即使是有重复数的情况,这个数也一定在排序后的中间位置上,用这个数去匹配去检验就可以,我的检验不够好,你可以从中间的下标,从中间为原点,左右匹配找到不同的数,然后通过下标计算直接得出大于小于的数的数量。第二种方式就是双向队列,弹头弹尾,注意检验就可以了。

    import java.util.Arrays;
    import java.util.Scanner;
    
    public class CCF201612_1 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int[] sourse = new int[n];
            for (int i = 0; i < n; i++) {
                sourse[i] = sc.nextInt();
            }
            Arrays.sort(sourse);
            if (n % 2 == 0) {
                int a = sourse[n / 2 - 1];
                int b = sourse[n / 2];
                if (a == b) {
                    int count = 0;
                    for (int i = 0; i < n; i++) {
                        if (sourse[i] < a) {
                            count++;
                        }
                        if (sourse[i] > a) {
                            count--;
                        }
                    }
                    if (count == 0) {
                        System.out.println(a);
                    } else {
                        System.out.println(-1);
                    }
                } else {
                    int countA = 0;
                    int countB = 0;
                    for (int i = 0; i < n; i++) {
                        if (sourse[i] < a) {
                            countA++;
                        }
                        if (sourse[i] > a) {
                            countA--;
                        }
                        if (sourse[i] < b) {
                            countB++;
                        }
                        if (sourse[i] > b) {
                            countB--;
                        }
                    }
                    if (countA == 0) {
                        System.out.println(a);
                    }
                    if (countB == 0) {
                        System.out.println(b);
                    } else {
                        System.out.println(-1);
                    }
                }
    
                return;
            }
            if (n % 2 == 1) {
                int a = sourse[n / 2];
                int count = 0;
                for (int i = 0; i < n; i++) {
                    if (sourse[i] < a) {
                        count++;
                    }
                    if (sourse[i] > a) {
                        count--;
                    }
                }
                if (count == 0) {
                    System.out.println(a);
                } else {
                    System.out.println(-1);
                }
                return;
            }
        }
    }

    试题编号:201612-2

    试题名称:工资计算

    image

    样例输入

    9255

    样例输出

    10000

    评测用例规模与约定

      对于所有评测用例,1 ≤ T ≤ 100000。

    思路:这个代码我写的很丑,这题也比较烦,数学的关系式推好了可以简化很多,不管是最后的折算计算出原值的结果,还是前面各种数据的转换,先写公式再做题,数学是编程的降维武器。

    import java.util.Scanner;
    
    public class CCF201612_2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int T = sc.nextInt();
            if (T <= 3500) {
                System.out.println(T);
                return;
            }
            int[][] range = new int[7][2];
            range[0][0] = 3500;
            range[0][1] = 3500;
            range[1][0] = (int) (range[0][0] + 1500 * (0.97));
            range[1][1] = 5000;
            range[2][0] = (int) (range[1][0] + (4500 - 1500) * (0.9));
            range[2][1] = 8000;
            range[3][0] = (int) (range[2][0] + (9000 - 4500) * (0.8));
            range[3][1] = 12500;
            range[4][0] = (int) (range[3][0] + (35000 - 9000) * (0.75));
            range[4][1] = 38500;
            range[5][0] = (int) (range[4][0] + (55000 - 35000) * (0.7));
            range[5][1] = 58500;
            range[6][0] = (int) (range[5][0] + (80000 - 55000) * (0.65));
            range[6][1] = 83500;
            int Index = 0;
            for (int i = 6; i >= 0; i--) {
                if (T > range[i][0]) {
                    Index = i;
                    break;
                }
            }
            double[] rate = new double[] { 0.97, 0.9, 0.8, 0.75, 0.7, 0.65, 0.55 };
            for (int i = (range[Index][0] / 100 + 1) * 100; i < 100001; i += 100) {
                if (T == (range[Index][0] + (i - range[Index][1]) * rate[Index])) {
                    System.out.println(i);
                    return;
                }
            }
    
        }
    }

    试题编号:201703-1

    试题名称:分蛋糕

    image

    样例输入

    6 9
          2 6 5 6 3 5

    样例输出

    3

    样例说明

      第一个朋友分到了前3块蛋糕,第二个朋友分到了第4、5块蛋糕,第三个朋友分到了最后一块蛋糕。

    评测用例规模与约定

      对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ k ≤ 10000,1 ≤ ai ≤ 1000。

    思路:排序之后很好解决,顺着给就行,大于需求就下一个,不够满足了就输出结构就行。

    import java.util.Arrays;
    import java.util.Scanner;
    
    public class CCF201703_1 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int k = sc.nextInt();
            int[] A = new int[n];
            for (int i = 0; i < n; i++) {
                A[i] = sc.nextInt();
            }
            if (n == 1) {
                System.out.println(1);
                return;
            }
            int ret = 0;
            int temp = 0;
            for (int i = 0; i < n; i++) {
                if (temp < k) {
                    temp += A[i];
                }
                if (temp >= k) {
                    temp = 0;
                    ret++;
                }
            }
            if (temp != 0) {
                ret++;
            }
            System.out.println(ret);
        }
    }

    试题编号:201703-2

    试题名称:学生排队

    image

    样例输入

    8
          3
          3 2
          8 -3
          3 -2

    样例输出

    1 2 4 3 5 8 6 7

    评测用例规模与约定

      对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ m ≤ 1000,所有移动均合法。

    思路:很简单的问题,其实用LinkedList也可以很好解决,毕竟有大量的移动操作,我的代码思路很简单,就顺着交换学生位置移动就行了。

    import java.util.Scanner;
    
    public class CCF201703_2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int m = sc.nextInt();
            int[] sourse = new int[n];
            for (int i = 0; i < n; i++) {
                sourse[i] = i + 1;
            }
            for (int i = 0; i < m; i++) {
                int num = sc.nextInt();
                int step = sc.nextInt();
                for (int j = 0; j < n; j++) {
                    if (sourse[j] == num) {
                        sourse = Move(sourse, j, step);
                        break;
                    }
                }
            }
            for (int i = 0; i < n; i++) {
                System.out.print(sourse[i] + " ");
            }
        }
    
        public static int[] Move(int[] sourse, int index, int step) {
            if (step == 0) {
                return sourse;
            } else if (step < 0) {// 向前动
                int temp = 0;
                if ((step * -1) >= index) {// 超出移动范围
                    if (index == 0) {
                        return sourse;
                    }
                    for (int i = index - 1; i >= 0; i--) {
                        temp = sourse[i];
                        sourse[i] = sourse[i + 1];
                        sourse[i + 1] = temp;
                    }
                    return sourse;
                } else {// 范围内的移动
                    for (int i = index - 1; i > index - 1 + step; i--) {
                        temp = sourse[i];
                        sourse[i] = sourse[i + 1];
                        sourse[i + 1] = temp;
                    }
                    return sourse;
                }
            } else {
                int temp = 0;
                if ((index + 1 + step) >= sourse.length) {
                    if (index == sourse.length - 1) {
                        return sourse;
                    }
                    for (int i = index; i < sourse.length - 1; i++) {
                        temp = sourse[i];
                        sourse[i] = sourse[i + 1];
                        sourse[i + 1] = temp;
                    }
                    return sourse;
                } else {
                    for (int i = index; i < index + step; i++) {
                        temp = sourse[i];
                        sourse[i] = sourse[i + 1];
                        sourse[i + 1] = temp;
                    }
                }
                return sourse;
            }
        }
    }

    试题编号:201709-1

    试题名称:打酱油

    image

    样例输入

    40

    样例输出

    5

    样例说明

      把40元分成30元和10元,分别买3瓶和1瓶,其中3瓶送1瓶,共得到5瓶。

    样例输入

    80

    样例输出

    11

    样例说明

      把80元分成30元和50元,分别买3瓶和5瓶,其中3瓶送1瓶,5瓶送2瓶,共得到11瓶。

    思路:先去满足优惠最高的,最好自己心算一下每一瓶的价格,然后依次满足较低的优惠,没办法再原价买,贪心思想。

    import java.util.Scanner;
    
    public class CCF201709_1 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int N = sc.nextInt() / 10;
            if (N < 2) {
                System.out.println(N);
                return;
            }
            int ret = 0;
            int bestNum = N / 5;
            ret = (N / 5) * 5 + (N / 5) * 2;
            int lease = N % 5;
            if (lease == 0) {
                System.out.println(ret);
                return;
            }
            ret += (lease / 3) * 4;
            lease = lease % 3;
            if (lease == 0) {
                System.out.println(ret);
                return;
            }
            ret += lease;
            System.out.println(ret);
        }
    }

    试题编号:201709-2

    试题名称:公共钥匙盒

    image

    样例输入

    5 2
          4 3 3
          2 2 7

    样例输出

    1 4 3 2 5

    样例说明

      第一位老师从时刻3开始使用4号教室的钥匙,使用3单位时间,所以在时刻6还钥匙。第二位老师从时刻2开始使用钥匙,使用7单位时间,所以在时刻9还钥匙。
      每个关键时刻后的钥匙状态如下(X表示空):
      时刻2后为1X345;
      时刻3后为1X3X5;
      时刻6后为143X5;
      时刻9后为14325。

    样例输入

    5 7
          1 1 14
          3 3 12
          1 15 12
          2 7 20
          3 18 12
          4 21 19
          5 30 9

    样例输出

    1 2 3 5 4

    评测用例规模与约定

      对于30%的评测用例,1 ≤ N, K ≤ 10, 1 ≤ wN, 1 ≤ s, c ≤ 30;
      对于60%的评测用例,1 ≤ N, K ≤ 50,1 ≤ wN,1 ≤ s ≤ 300,1 ≤ c ≤ 50;
      对于所有评测用例,1 ≤ N, K ≤ 1000,1 ≤ wN,1 ≤ s ≤ 10000,1 ≤ c ≤ 100。

    思路:先根据取钥匙的时间排序,然后再根据还钥匙的时间排序,如果还钥匙的时间相同,按照提示,先把编号小的钥匙换回去,检测放钥匙的数组,只要空就能放回去。代码完全按照提示的思路,排完序后先还钥匙(按序号小优先),然后再借钥匙。

    import java.util.ArrayList;
    import java.util.Scanner;
    
    public class CCF201709_2 {
        public static class Teacher {
            public int key;
            public int start_time;
            public int time;
            public int return_time;
    
            Teacher(int key, int start_time, int time) {
                this.key = key;
                this.start_time = start_time;
                this.time = time;
                this.return_time = start_time + time;
            }
    
            public int getKey(int nowtime) {
                if (nowtime == start_time) {
                    return key;
                } else {
                    return 0;
                }
            }
    
            public int returnKey(int nowtime) {
                if (nowtime == return_time) {
                    return key;
                } else {
                    return 0;
                }
            }
        }
    
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int N = sc.nextInt();
            int K = sc.nextInt();
            ArrayList al_get = new ArrayList();
            int endTime = 0;
            for (int i = 0; i < K; i++) {
                Teacher teacher = new Teacher(sc.nextInt(), sc.nextInt(), sc.nextInt());
                if (teacher.return_time > endTime) {
                    endTime = teacher.return_time;
                }
                al_get.add(teacher);
            }
            for (int i = 0; i < K; i++) {
                for (int j = 0; j < K - i - 1; j++) {
                    Teacher teacher1 = (Teacher) al_get.get(j);
                    Teacher teacher2 = (Teacher) al_get.get(j + 1);
                    if (teacher1.start_time > teacher2.start_time) {
                        int tempKey = teacher1.key;
                        int tempStart_time = teacher1.start_time;
                        int tempTime = teacher1.time;
                        int tempReturn_time = teacher1.return_time;
                        teacher1.key = teacher2.key;
                        teacher1.start_time = teacher2.start_time;
                        teacher1.time = teacher2.time;
                        teacher1.return_time = teacher2.return_time;
                        teacher2.key = tempKey;
                        teacher2.start_time = tempStart_time;
                        teacher2.time = tempTime;
                        teacher2.return_time = tempReturn_time;
                    }
                }
            }
    
            ArrayList al_return = al_get;
            for (int i = 0; i < K; i++) {
                for (int j = 0; j < K - i - 1; j++) {
                    Teacher teacher1 = (Teacher) al_return.get(j);
                    Teacher teacher2 = (Teacher) al_return.get(j + 1);
                    if (teacher1.return_time > teacher2.return_time) {
                        swap(teacher1, teacher2);
                        continue;
                    }
                    if (teacher1.return_time == teacher2.return_time) {
                        if (teacher1.key > teacher2.key) {
                            swap(teacher1, teacher2);
                            continue;
                        }
                    }
                }
            }
            int[] Key = new int[N + 1];
            for (int i = 0; i < N + 1; i++) {
                Key[i] = i;
            }
            for (int nowtime = 1; nowtime <= endTime; nowtime++) {
    
                for (int j = 0; j < K; j++) {
                    Teacher teacher = (Teacher) al_return.get(j);
                    if (teacher.returnKey(nowtime) != 0) {
                        for (int i = 1; i < N + 1; i++) {
                            if (Key[i] == 0) {
                                Key[i] = teacher.returnKey(nowtime);
                                break;
                            }
                        }
                    }
                }
    
                for (int j = 0; j < K; j++) {
                    Teacher teacher = (Teacher) al_get.get(j);
                    if (teacher.getKey(nowtime) != 0) {
                        for (int i = 1; i < N + 1; i++) {
                            if (Key[i] == teacher.key) {
                                Key[i] = 0;
                                break;
                            }
                        }
                    }
                }
            }
            for (int i = 1; i < N + 1; i++) {
                System.out.print(Key[i] + " ");
            }
        }
    
        public static void swap(Teacher teacher1, Teacher teacher2) {
            int tempKey = teacher1.key;
            int tempStart_time = teacher1.start_time;
            int tempTime = teacher1.time;
            int tempReturn_time = teacher1.return_time;
            teacher1.key = teacher2.key;
            teacher1.start_time = teacher2.start_time;
            teacher1.time = teacher2.time;
            teacher1.return_time = teacher2.return_time;
            teacher2.key = tempKey;
            teacher2.start_time = tempStart_time;
            teacher2.time = tempTime;
            teacher2.return_time = tempReturn_time;
        }
    }

    试题编号:201712-1

    试题名称:最小差值

    image

    样例输入

    5
          1 5 4 8 20

    样例输出

    1

    样例说明

      相差最小的两个数是5和4,它们之间的差值是1。

    样例输入

    5
          9 3 6 1 3

    样例输出

    0

    样例说明

      有两个相同的数3,它们之间的差值是0.

    数据规模和约定

      对于所有评测用例,2 ≤ n ≤ 1000,每个给定的整数都是不超过10000的正整数。

    思路:先排序,然后比较相邻,记录最小

    import java.util.Arrays;
    import java.util.Scanner;
    
    public class CCF201712_1 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int[] A = new int[n];
            for (int i = 0; i < n; i++) {
                A[i] = sc.nextInt();
            }
            Arrays.sort(A, 0, A.length);
            int min = A[1] - A[0];
            for (int i = 1; i < n; i++) {
                if ((A[i] - A[i - 1]) < min) {
                    min = A[i] - A[i - 1];
                }
            }
            System.out.println(min);
        }
    }

    试题编号:201712-2

    试题名称:游戏

    image

    样例输入

    5 2

    样例输出

    3

    样例输入

    7 3

    样例输出

    4

    数据规模和约定

      对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ k ≤ 9。

    思路:约瑟夫环问题,因为需要经常删除元素,所以使用LinkedList速度会快一点,就是一个下标的循环,分开判断即可简单解决。

    import java.util.LinkedList;
    import java.util.Scanner;
    
    public class CCF201712_2 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int k = sc.nextInt();
            if (n == 1) {
                System.out.println(1);
                return;
            }
            LinkedList ll = new LinkedList();
            for (int i = 1; i < n + 1; i++) {
                ll.add(i);
            }
            int count = 1;
            int index = 0;
            while (ll.size() > 1) {
                if ((count % k == 0) || (count % 10 == k)) {
                    ll.remove(index);
                    count++;
                    if (index == ll.size()) {
                        index = 0;
                    }
                    continue;
                }
                if (index == ll.size() - 1) {
                    index = 0;
                } else {
                    index++;
                }
                count++;
            }
            System.out.println(ll.get(0));
        }
    }

    试题编号:201803-1

    试题名称:跳一跳

    image

    样例输入

    1 1 2 2 2 1 1 2 2 0

    样例输出

    22

    数据规模和约定

      对于所有评测用例,输入的数字不超过30个,保证0正好出现一次且为最后一个数字。

    思路:比较2的时候通过一个单独的参数去增加得分倍数即可,发现下一次不是2时,再把这个单独的参数初始化即可。

    import java.util.Scanner;
    
    public class CCF201803_1 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int temp = sc.nextInt();
            int ret = temp;
            int last = temp;
            int prise = 2;
            while (temp != 0) {
                temp = sc.nextInt();
                if (temp == 0) {
                    continue;
                }
                if (temp == 1) {
                    if (last == 2) {// 1的上一个是2,终结了,重新刷新
                        prise = 2;
                    }
                    ret += 1;
                    last = 1;
                    continue;
                }
                if (last == 2) {
                    prise += 2;
                }
                ret += prise;
                last = 2;
    
            }
            System.out.println(ret);
        }
    }

    试题编号:201803-2

    试题名称:碰撞的小球

    image

    样例输入

    3 10 5
          4 6 8

    样例输出

    7 9 9

    思路:模拟题,一直觉得这种题挺有意思的,但这题不复杂,主要就是一个撞墙(与墙下标重叠)互撞(与另一个球下标重叠)方向和速度也很简单,一秒一秒模拟即可。

    但是因为最后需要按小球序号输出,需要单独记录一下num

    import java.util.ArrayList;
    import java.util.Scanner;
    
    public class CCF201803_2 {
        public static class Ball {
            public int num;
            public int index;
            public int direction = 1;
            public int flag = 1;
    
            public Ball(int num, int index) {
                this.num = num;
                this.index = index;
            }
    
            public Ball() {
                this.num = 0;
                this.index = 0;
            }
    
            public void changeFinded() {
                flag *= -1;
            }
    
            public void changeDirection() {
                direction *= -1;
            }
    
            public void step() {
                index += direction;
            }
        }
    
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int L = sc.nextInt();
            int t = sc.nextInt();
            ArrayList al = new ArrayList();
            for (int i = 1; i <= n; i++) {
                Ball ball = new Ball(i, sc.nextInt());
                al.add(ball);
            }
            for (int i = 0; i < t; i++) {
                for (int j = 0; j < n; j++) {
                    Ball ball1 = (Ball) al.get(j);
                    if (ball1.index == L) {// 检测是否撞墙
                        ball1.changeDirection();
                    }
                    for (int k = 0; k < n; k++) {
                        Ball ball2 = (Ball) al.get(k);
                        if (ball2.index == ball1.index) {// 下标重复
                            if (ball2.flag == 1 && ball1.flag == 1) {// 第一次遇到
                                if (ball2.num != ball1.num) {// 并且不是同一颗球
                                    ball1.changeDirection();
                                    ball1.changeFinded();
                                    ball2.changeDirection();
                                    ball2.changeFinded();
                                    break;
                                }
                            } else {// 第二次遇到改flag,但不操作
                                ball1.changeFinded();
                                ball2.changeFinded();
                                break;
                            }
                        }
                    }
    
                }
                for (int j = 0; j < n; j++) {
                    Ball ball1 = (Ball) al.get(j);
                    ball1.step();
                }
            }
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n - i - 1; j++) {
                    Ball ball1 = (Ball) al.get(j);
                    Ball ball2 = (Ball) al.get(j + 1);
                    if (ball1.num > ball2.num) {
                        int tempNum = ball1.num;
                        int tempIndex = ball1.index;
                        ball1.num = ball2.num;
                        ball1.index = ball2.index;
                        ball2.num = tempNum;
                        ball2.index = tempNum;
                    }
                }
            }
            for (int i = 0; i < n; i++) {
                Ball ball = (Ball) al.get(i);
                System.out.print(ball.index + " ");
            }
        }
    }

    试题编号:201809-1

    试题名称:卖菜

    image

    样例输入

    8
          4 1 3 1 6 5 17 9

    样例输出

    2 2 1 3 4 9 10 13

    数据规模和约定

      对于所有评测用例,2 ≤ n ≤ 1000,第一天每个商店的菜价为不超过10000的正整数。

    思路:很简单,第一个和最后一个(n,下标n-1)分开判断,其他的与相邻就好,考虑特殊情况,2个店,1个店即可。

    import java.util.Scanner;
    
    public class CCF201809_1 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n=sc.nextInt();
            int[] A=new int[n];
            for(int i=0;i<n;i++) {
                A[i]=sc.nextInt();
            }
            if(n==2) {
                System.out.print((A[0]+A[1])/2+" ");
                System.out.print((A[0]+A[1])/2);
                return;
            }
            for(int i=0;i<n;i++) {
                if(i==0) {
                    System.out.print((A[i]+A[i+1])/2+" ");
                    continue;
                }
                if(i==n-1) {
                    System.out.print((A[i-1]+A[i])/2+" ");
                    break;
                }
                System.out.print((A[i-1]+A[i]+A[i+1])/3+" ");
            }
        }
    }

    试题编号:201809-2

    试题名称:买菜

    image

    样例输入

    4
          1 3
          5 6
          9 13
         14 15
         2 4
         5 7
        10 11
        13 14

    样例输出

    3

    数据规模和约定

      对于所有的评测用例,1 ≤ n ≤ 2000, ai < bi < ai+1,ci < di < ci+1,对于所有的i(1 ≤ i ≤ n)有,1 ≤ ai, bi, ci, di ≤ 1000000。

    思路:用hashset的去重功能,只要插入的时候返回了false,就说明已经有人在那里了,就可以过去聊天。

    import java.util.HashSet;
    import java.util.Scanner;
    
    public class CCF201809_2 {
        public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            int n=sc.nextInt();
            HashSet hs=new HashSet();
            int x=0;
            int y=0;
            int ret=0;
            for(int i=0;i<n*2;i++) {
                x=sc.nextInt();
                y=sc.nextInt();
                for(int j=x;j<y;j++) {
                    if(hs.add(j)==false) {
                        ret++;
                    }
                }
            }
            System.out.println(ret);
        }
    }

    试题编号:201812-1

    试题名称:小明上学

    image

    样例输入

    30 3 30
          8
          0 10
          1 5
          0 11
          2 2
          0 6
          0 3
          3 10
          0 3

    样例输出

    70

    样例说明

      小明先经过第一段道路,用时 10 秒,然后等待 5 秒的红灯,再经过第二段道路,用时 11 秒,然后等待 2 秒的黄灯和 30 秒的红灯,再经过第三段、第四段道路,分别用时6、3秒,然后通过绿灯,再经过最后一段道路,用时 3 秒。共计 10 + 5 + 11 + 2 + 30 + 6 + 3 + 3=70 秒。

    评测用例规模与约定

       测试点 1, 2 中不存在任何信号灯。
         测试点 3, 4 中所有的信号灯在被观察时均为绿灯。
        测试点 5, 6 中所有的信号灯在被观察时均为红灯。
       测试点 7, 8 中所有的信号灯在被观察时均为黄灯。
       测试点 9, 10 中将出现各种可能的情况。

    思路:去计算当前时间落在的区间范围即可。

    import java.util.Scanner;
    
    public class CCF201812_1 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            Long r=sc.nextLong();
            Long y=sc.nextLong();
            Long g=sc.nextLong();
            int n=sc.nextInt();
            Long[][] A=new Long[n][2];
            int ret=0;
            for(int i=0;i<n;i++) {
                A[i][0]=sc.nextLong();
                A[i][1]=sc.nextLong();
                if(A[i][0]==0) {
                    ret+=A[i][1];
                    continue;
                }
                if(A[i][0]==1) {
                    ret+=A[i][1];
                    continue;
                }
                if(A[i][0]==2) {
                    ret+=A[i][1]+r;
                    continue;
                }
                if(A[i][0]==3) {
                    if(A[i][1]==0) {
                        ret+=r+y;
                    }
                    continue;
                }
            }
            System.out.println(ret);
        }
    }

    试题编号:201812-2

    试题名称:小明放学

    image

    样例输入

    30 3 30
          8
          0 10
          1 5
          0 11
          2 2
          0 6
          0 3
          3 10
          0 3

    样例输出

    46

    样例说明

      小明先经过第一段路,用时 10 秒。第一盏红绿灯出发时是红灯,还剩 5 秒;小明到达路口时,这个红绿灯已经变为绿灯,不用等待直接通过。接下来经过第二段路,用时 11 秒。第二盏红绿灯出发时是黄灯,还剩两秒;小明到达路口时,这个红绿灯已经变为红灯,还剩 11 秒。接下来经过第三、第四段路,用时 9 秒。第三盏红绿灯出发时是绿灯,还剩 10 秒;小明到达路口时,这个红绿灯已经变为红灯,还剩两秒。接下来经过最后一段路,用时 3 秒。共计 10+11+11+9+2+3 = 46 秒。

    评测用例规模与约定

      有些测试点具有特殊的性质:
      * 前 2 个测试点中不存在任何信号灯。
      测试点的输入数据规模:
      * 前 6 个测试点保证 n ≤ 103
      * 所有测试点保证 n ≤ 105

    思路:有一个比第一题更好的思路,就是不去计算剩余时间,用当前区间减去剩余时间,去计算初始时间,然后加上总的经过时间,在去折算区间,问题会变得简单的多。这一题在完成转化之后,与上一题情况类似,所以不粘贴代码了,仅提供思路。

  • 相关阅读:
    利用 pandas库读取excel表格数据
    Spark学习笔记3——RDD(下)
    Spark学习笔记2——RDD(上)
    Spark学习笔记1——第一个Spark程序:单词数统计
    Spark学习笔记0——简单了解和技术架构
    java标识符和关键字
    数据库事务ACID特性(原子性、一致性、隔离性、持久性)
    大数据系统的运行
    虚拟机和hadoop
    大数据基础1
  • 原文地址:https://www.cnblogs.com/STK0210/p/10549675.html
Copyright © 2011-2022 走看看