0
点赞
收藏
分享

微信扫一扫

第九届蓝桥杯JavaA组(2018年)省赛真题解析

第九届蓝桥杯JavaA组(2018年)省赛真题解析

1.分数

  • 1/1+1/2+1/4+1/8+1/16+…
  • 每项是前一项的一半,如果一共有20项,求这个和是多少
  • 结果用分数表示,类似:
  • 3/2,当然这这是加了前2项而已,分子分母要求互质,
  • 提交的是已经约分过的分数。

思想:求出分子分母,同除最大公约数即可。

/**
 * 1.分数
 * 1/1+1/2+1/4+1/8+1/16+...
 * 每项是前一项的一半,如果一共有20项,求这个和是多少
 * 结果用分数表示,类似:
 * 3/2,当然这这是加了前2项而已,分子分母要求互质,
 * 提交的是已经约分过的分数。
 */
public class Main {
    static int n ;
    public static void main(String[] args) {
        int index = 1, sum = 0 ;
        for(int i=1; index<=20; i*= 2){
            n = i ;
            sum += i ;
            index ++ ;
        }
        System.out.println(sum/gcd(sum,n) + "/" + n/gcd(sum,n));
    }

    private static int gcd(int sum, int n) {
        if(n==0){
            return sum ;
        }
        return gcd(n, sum%n) ;
    }
}

2.星期一
思想:做个平闰年判断,累积天数,然后除以7就是星期一的天数。

import static java.time.Year.isLeap;

public class Main1 {
    public static void main(String[] args) {
        long days = 0 ;
        for(int year=1901; year<=2000; year++){
            if(isLeap(year)){
                days += 366 ;
            }else{
                days += 365 ;
            }
        }
        System.out.println(days/7);
    }
    /**
    private static boolean leap(int year){
        if((year%4 == 0 && year%100!=0) || year%400==0){
            return true ;
        }
        return false ;
    }
     */
}

3.复数幂
思想:这个需要用到Java特有的BigInteger,然后迭代找出虚部和实部即可。

import java.math.BigInteger;

/**
 * 3.复数幂
 * 设i为虚数单位,对任意正整数n,(2+3i)^n的实部和虚部都是整数,
 * 求(2+3i)^123456等于多少,这个数字很大,要求精确表示,
 */
public class Main {
    static BigInteger aa, bb ;
    public static void main(String[] args) {
        BigInteger a = new BigInteger("2") ;
        BigInteger b = new BigInteger("3" ) ;
        aa = null;
        bb = null ;
        for(int i=1; i<=123455; i++){
            aa = a.multiply(new BigInteger("2")).subtract(b.multiply(new BigInteger("3"))) ;
            bb = a.multiply(new BigInteger("3")).add(new BigInteger("2")) ;
            a = aa ;
            b = bb ;
        }
        System.out.println(a + "" + (b.compareTo(BigInteger.ONE) > 0 ? "+" : "") + b + "i"  );
    }
}

4.方格计数
思想:求出一个象限满足限制条件的,乘以4即可。

 * 4.方格计数
 */
public class Main {
    public static void main(String[] args) {
        long ans = 0 ;
        long N = 50000;
        long y = N ;
        for(long x=1; x<=N; x++){
            while(y>0 && x*x+y*y>N*N){
                y -- ;
            }
            ans += y ;
        }
        System.out.println(4*ans);
    }
}

5.代码填空:略

6.航班日期
思想:规律题,两次航行的时间差求和取平均就是航行时间。

 * 4.方格计数
 */
/**
 * 航班日期
 3
 17:48:19 21:57:24
 11:05:18 15:14:23
 17:21:07 00:31:46 (+1)
 23:02:41 16:13:20 (+1)
 10:19:19 20:41:24
 22:19:04 16:41:09 (+1)

 */

import java.text.ParseException;
        import java.text.SimpleDateFormat;
        import java.util.Date;
        import java.util.Scanner;

public class Main1 {
    static int T ;
    static Scanner input = new Scanner(System.in) ;
    public static void main(String[] args) throws ParseException {
        T = input.nextInt() ;
        input.nextLine() ;
        for(int i=0; i<T; i++){
            long t1 = getTime() ;
            long t2 = getTime() ;
            long t = (t1+t2) / 2 ;
            System.out.printf("%02d:%02d:%02d\n",t/3600,t/60%60, t%60);
        }
    }

    private static long getTime() throws ParseException {
        String time = input.nextLine() ;
        String [] split = time.split(" ") ;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss") ;
        Date t1 = simpleDateFormat.parse(split[0]) ;
        Date t2 = simpleDateFormat.parse(split[1]) ;
        int d = 0 ;
        if(split.length==3){
            d = Integer.parseInt(split[2].substring(2,3)) ;
        }
        return d*24*3600 + t2.getTime()/1000 - t1.getTime()/1000 ;
    }
}


7.三体攻击
思想:这题比较,我用的是暴力法,可以通过部分测试用例,比较好的方法是二分加三维前缀和,但是赛场上还是用暴力迅速得分靠谱。

import java.util.Scanner;

/**
 * 7.三体攻击
 *
 */
public class Main {
    static int A,B,C,m ;
    static int [][] attack ;
    static int [][][] a ;
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in) ;
        A = input.nextInt() ;
        B = input.nextInt() ;
        C = input.nextInt() ;
        m = input.nextInt() ;
        a = new int [A+1][B+1][C+1] ; //用来存储每个战舰的生命值
        attack = new int [m][7] ;//记录每一轮攻击的7个数据
        for(int i=1; i<=A; i++){ //记录战舰的生命值
            for(int j=1; j<=B; j++){
                for(int k=1; k<=C; k++){
                    a[i][j][k] = input.nextInt();
                }
            }
        }
        for(int i=0; i<m; i++){ //记录攻击信息
            for(int j=0; j<7; j++){
                attack[i][j] = input.nextInt() ;
            }
        }
        for(int round=0; round<m; round++){ //攻击轮数
            for(int i=attack[round][0]; i<=attack[round][1]; i++){
                for(int j=attack[round][2]; j<=attack[round][3]; j++){
                    for(int k=attack[round][4]; k<=attack[round][5]; k++){
                        if(a[i][j][k] > 0){ //受到攻击生命值减少
                            a[i][j][k] -= attack[round][6] ;
                        }else{ //生命值小于0,爆炸
                            System.out.println(round+1);
                            return ;
                        }
                    }
                }
            }
        }
    }
}

8.全球变暖
思想:搜索+标记
第一轮搜索算出有多少岛屿 ;
然后迭代遍历将不会被淹没的标记出来
第二轮搜出出不会被淹没的岛屿数量
两轮搜索的结果相减就是被淹没的岛屿数量

import java.util.Scanner;

/**
 * 8.全球变暖
 */

/**
 7
 .......
 .##....
 .##....
 ....##.
 ..####.
 ...###.
 .......
 */
public class Main {
    static char [][] a ;
    static int N ;
    static int cnt = 0, cnt1 ;
    static int [] offsetX = {-1,1,0,0} ;
    static int [] offsetY = {0,0,-1,1} ;
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in) ;
        N = input.nextInt() ;
        a = new char [N][N] ;
        String s = "" ;
        int index = 0 ;
        for(int i =0; i<N; i++){
                s += input.next() ;
        }
        for(int i=0; i<N; i++){
            for(int j=0; j<N; j++){
                a[i][j] += s.charAt(index++) ;
            }
        }

        for(int i=0; i<N; i++){
            for(int j=0; j<N; j++){
                if(a[i][j] == '#') {
                    dfs1(a, i, j);
                    cnt ++ ;//计算岛屿数量
                }
            }
        }
        for(int i=1; i<N-1; i++) { //还没被淹没的标记为#
            for (int j = 1; j < N-1; j++) {
                if(a[i][j] == '1' && a[i-1][j] == '1' && a[i+1][j]=='1' && a[i][j-1]=='1' && a[i][j+1]=='1'){
                    a[i][j] = '#' ;
                }
            }
        }
        for(int i=0; i<N; i++){
            for(int j=0; j<N; j++){
                if(a[i][j] == '#') {
                    dfs1(a, i, j);
                    cnt1 ++ ;//计算未被淹没的岛屿数量
                }
            }
        }
        System.out.println(cnt-cnt1); //被淹没的岛屿数量
    }

    private static void dfs1(char[][] a, int x, int y) {
        a[x][y] = '1' ;
        for(int i=0; i<4; i++){
            int nx = x + offsetX[i] ;
            int ny = y + offsetY[i] ;
            if(nx<0 || ny<0 || nx>N || ny>N){
                continue;
            }
            if(a[nx][ny] == '#')
            dfs1(a, nx, ny) ;
        }
    }
}

9.倍数问题
方法1:暴力枚举
三层循环,从大到小依次枚举,测试用例数据不是很大,可以通过大多数测试用例。

import java.util.Arrays;
import java.util.Scanner;

/**
 * 9.倍数问题
 *
 */
public class Main {
    static int n, K ;
    static int [] a ;
    static int sum ;
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in)  ;
        n = input.nextInt() ;
        K = input.nextInt() ;
        a = new int [n] ;
        for(int i=0; i<n; i++){
            a[i] = input.nextInt() ;
        }
        Arrays.sort(a) ;
        for(int i=n-1; i>0; i--){ //可以通过60%的测试用例
            for(int j=i-1; j>0; j--){
                for(int k=j-1; k>0; k--){
                    sum = a[i] + a[j] + a[k] ;
                    if(sum % K== 0){
                        System.out.println(sum);
                    }
                }
            }
        }

    }
}

方法2:排序+搜索
由大到小排序,搜索枚举,找到第一个就结束


import java.util.Arrays;
import java.util.Scanner;

/**
 * 从小到大排序,然后搜索枚举
 */
public class Main1 {
    static int n, K ;
    static int [] a ;
    static int [] c ;
    static int [] b ;
    static boolean flag = false ;
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in) ;
        n = input.nextInt() ;
        K = input.nextInt() ;
        a = new int [n+1] ;
        c = new int [n+1] ;
        b = new int [4] ;
        c[0] = Integer.MAX_VALUE ;
        for(int i=1; i<=n; i++){
            a[i] = input.nextInt() ;
        }
        Arrays.sort(a) ;
        for(int i=1; i<=n; i++){
            c[i] = a[n-i+1] ;
        }
        dfs(c, n, 1) ;
    }

    private static void dfs(int[] c, int n, int s) {
        if(flag){
            return ;
        }
        if(s==4){
            int sum = b[1] + b[2] + b[3] ;
            if(sum%K==0){
                System.out.println(sum);
                flag = true ;
            }
            return ;
        }
        for(int i=1; i<=n; i++){
            if(c[i]<c[s-1]){
                b[s] = c[i] ;
                dfs(c, n, s+1) ;
            }
        }
    }
}

10.付账问题
思想:贪心策略,拥有的钱由小到大排序,每一次遍历拥有的钱小于均摊值,则全部出,否则,所有人出均摊值,局部最优,全局也最优。

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    static double  S, ave, avg = 0, s=0;
    static int n ;
    static double [] a ;
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in) ;
        n = input.nextInt() ;
        S = input.nextDouble() ;
        a = new double[n] ;
        for(int i=0; i<n; i++){
            a[i] = input.nextDouble() ;
        }
        avg = S / n ;
        ave = avg ;
        Arrays.sort(a) ;
        for(int i=0; i<n; i++){
            if(ave > a[i]){
                S -= a[i] ;
                s += (avg-a[i]) * (avg-a[i]) ;
                ave= S / (n-i-1) ;
            }else{
                double avg1 = S / (n-i) ;
                s += (avg-avg1)*(avg-avg1)*(n-i) ;
                break ;
            }
        }
        System.out.printf("%.4f", Math.sqrt(s/n));
    }
}

举报

相关推荐

0 条评论