第九届蓝桥杯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 = b.multiply(new BigInteger("2")).add(a.multiply(new BigInteger("3"))) ;
            a = aa ;
            b = bb ;
        }
        System.out.println(a + "" + (b.compareTo(BigInteger.ONE)<=0 ? "" : "+") + b + "i");
    }
}


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.航班日期
思想:规律题,两次航行的时间差求和取平均就是航行时间。


/**
 * 航班日期
 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));
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
2022蓝桥杯Java A是中国著名的计算机竞赛之一,该比赛旨在发掘和培养优秀的Java程序设计人才。参赛者需要具备一定的Java编程基础和算法思维能力,通过解决一系列实际问题来展示自己的技术水平。 蓝桥杯Java A比赛内容将涉及Java语言基础知识、面向对象编程、数据结构与算法、数据库等方面。参赛选手需要通过模拟真实的工作场景,设计和实现各种功能模块,展现出自己解决问题的能力和代码的优雅性。 蓝桥杯Java A比赛对于参赛者来说是一次难得的锻炼机会。通过参加比赛,可以学习到实际项目中常用的技术和解决问题的思路,提高自己的编程能力。同时,这也是一个展示自己才华和与其他选手竞争的舞台,可以通过与其他优秀选手的交流互动,拓宽自己的视野,并且与同龄人一起追求计算机编程的进步。 参加蓝桥杯Java A比赛,不仅可以提升自己的技术能力,还能为自己的未来发展增加一份宝贵的竞赛经验。很多优秀的程序员和企业都非常看重蓝桥杯的参赛者,因为这代表着他们在编程领域具备一定的实力和潜力。 总而言之,参加2022蓝桥杯Java A是一个对自己实力的检验和提高的机会,同时也是一个与其他优秀选手竞争的平台,可以通过比赛锻炼自己的技术能力和解决问题的能力。参赛者在比赛中要保持冷静和耐心,学会与其他选手交流和合作,相信通过努力,一定能够在比赛中取得好的成绩。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nuist__NJUPT

给个鼓励吧,谢谢你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值