第九届蓝桥杯JavaB组(2018年)省赛题解

Posted nuist__NJUPT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第九届蓝桥杯JavaB组(2018年)省赛题解相关的知识,希望对你有一定的参考价值。

第九届蓝桥杯JavaB组(2018年)省赛题解

开开心心刷题,快快乐乐学习,踏踏实实工作,路漫漫其修远兮,吾将上下而求索!!!

1.第几天
热身题,注意闰年二月是29天就可以。

/**
 * 1.第几天
 *
 */
public class Main 
    static int days = 0 ;
    static int year = 2000 ;
    public static void main(String[] args) 

        for(int i=1; i<=5; i++) 
            switch (i)
                case 1 : case 3 : days+= 31; break ;
                case 2 : days += (isLeap(year)) ?   29 :  28; break ;
                case 4 : days += 30 ; break;
                case 5 : days += 4 ; break;
            
        
        System.out.println(days);
    

    private static boolean isLeap(int year) 
        if((year % 4 == 0 && year % 100 != 0) || year%400==0)
            return true ;
        
        return false ;
    


2.方格计数
思想:四个象限,求出一个,然后乘以4即可。
xx+yy<=r*r为满足条件的情况。

/**
 * 2.方格计数
 * 以某个小方格顶点为圆形,画一个半径为1000的圆,
 * 计算出圆里面有多少个完整的小方格。
 */
public class Main 
    public static void main(String[] args) 
        int r = 1000 ;
        int y = r ;
        int ans = 0 ;
        for(int x=1; x<=r; x++)
            while(y>0 && x*x+y*y>r*r)
                y -- ;
            
            ans += y ;
        

        System.out.println(ans*4);
    


3.复数幂
思想:用到了Java的BigInteger,就是如下公式的迭代
(a+bi)* (2+3i)
实部:a * 2-b * 3
虚部:a* 3i + 2 * bi

import java.math.BigInteger;

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.测试次数
思想:递推思想,就是动态规划,这题很容易以为是二分思想,其实和二分没有关系。
1,2,3部手机面对n层楼的最佳策略,仔细观察会发现由递推关系,可以得到递推关系式。

当1部手机,n层楼,测试次数如下:
f1[n] = n
当2部手机,n层楼,测试次数如下:
f2[n]=min(for i in n (max(1+f2[n-i],1+f1[i-1])))
当3部手机,n层楼,测试次数如下:
f3[n]=min(for i in n (max(1+f3[n-i],1+f2[i-1])))

/**
 * 4.测试次数
 * 误区:很容易以为是二分,其实考的是动态规划
 */
public class Main 
    static int N = 1000;
    static int [] f1 ;
    static int [] f2 ;
    static int [] f3 ;
    public static void main(String[] args) 
      f1 = new int [N+1] ;
      f2 = new int [N+1] ;
      f3 = new int [N+1] ;
      for(int i=1; i<=N; i++)
          //1部手机测试次数
          f1[i] = i ;
      
      //2部手机测试次数
      for(int i=1; i<=N; i++)
          int ans = Integer.MAX_VALUE ;
          for(int j=1; j<=i; j++)
              int max = Math.max(1+f2[i-j], 1+f1[j-1]) ;
              ans = Math.min(ans, max) ;
          
          f2[i] = ans ;
      
      //3部手机的测试次数
        for(int i=1; i<=N; i++)
            int ans = Integer.MAX_VALUE ;
            for(int j=1; j<=i; j++)
                //第i层运气最差的情况
                int max = Math.max(1+f3[i-j], 1+f2[j-1]) ;
                //每层运气最差的情况下,选个测试次数最少的
                ans = Math.min(max, ans) ;
            
            f3[i] = ans ;
        
        System.out.println(f3[N]);
    


5.代码填空:略

6.递增三元组

方法1:暴力枚举

import java.util.Scanner;

/**
 * 6.递增三元组
 */
public class Main 
    static int N, cnt = 0 ;
    static int [] a ;
    static int [] b ;
    static int [] c ;
    public static void main(String[] args) 
        Scanner input = new Scanner(System.in) ;
        N = input.nextInt() ;
        a = new int [N] ;
        b = new int [N] ;
        c = new int [N] ;

        for(int i=0; i<N; i++)
            a[i] = input.nextInt() ;
        
        for(int i=0; i<N; i++)
            b[i] = input.nextInt() ;
        
        for(int i=0; i<N; i++)
            c[i] = input.nextInt() ;
        

        for(int i=0; i<N;i++)
            for(int j=0; j<N; j++)
                for(int k=0; k<N; k++)
                    if(a[i] < b[j] && a[i] < c[k] && b[j]<c[k])
                        cnt ++ ;
                    
                
            
        
        System.out.println(cnt);
    


方法2:固定b数组,查询a,c数组,查询过的不再需要扫描,节约时间


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

public class Main1 
    static int N ;
    static int [] a ;
    static int [] b ;
    static int [] c ;
    public static void main(String[] args) 
        Scanner input = new Scanner(System.in) ;
        N = input.nextInt() ;
        a = new int [N] ;
        b = new int [N] ;
        c = new int [N] ;
        for(int i=0; i<N; i++)
            a[i] = input.nextInt() ;
        
        for(int i=0; i<N; i++)
            b[i] = input.nextInt() ;
        
        for(int i=0; i<N; i++)
            c[i] = input.nextInt() ;
        
        Arrays.sort(a) ;
        Arrays.sort(b) ;
        Arrays.sort(c) ;
        int j=0, k=0, ans = 0 ;
        /**固定b数组,查询a,c数组
         * 由于所有的三个数组都已经排过序,
         * 所以查过的,后面不需要再次查询
         */
        for(int i=0; i<N; i++)
            while(j<N && b[i]>a[j])
                j ++ ;
            
            while(k<N && b[i]>=c[k])
                k ++ ;
            
            ans += j * (N - k) ;
        
        System.out.println(ans);

    


7.螺旋直线
思想:这题十分巧妙,可以把左下角的那条线旋转90度,组成正方形,对每个个坐标先判断内部有多少正方形,求正方形的周长area = 4 * n * (n-1) ;,然后再判断坐标在水平方向还是在树枝方向,
水平方向: sum += (8*n-d1-d2) ;
竖直方向: sum += (d1+d2) ;

import java.util.Scanner;

/**
 * 7.螺旋折线
 * 规律题:把所有的左下角的竖线旋转90°
 * 组成正方形,然后再计算(x,y)的dist(x,y)
 */
public class Main1 
    static long x, y ;
    public static void main(String[] args) 
        Scanner input = new Scanner(System.in) ;
        x = input.nextLong() ;
        y = input.nextLong() ;
        long n = Math.max(x, y) ; //判断在哪个正方形上
        long area = 4 * n * (n-1) ; //已有正方形的周长

        long d1 = x + n ;
        long d2 = y + n ;
        long sum = 0 ;
        if(x < y)
         sum += (d1+d2) ;
        else
            sum += (8*n-d1-d2) ;
        
        System.out.println(sum+area);

    


8.日志统计

方法1:数组标记法

import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

public class Main 
    static int N, D, K, ts, id ;
    static long [][] a = new long [10000][10000] ;
    static Set<Integer> set = new TreeSet<>() ;
    public static void main(String[] args) 
        Scanner input = new Scanner(System.in) ;
        N = input.nextInt() ;
        D = input.nextInt() ;
        K = input.nextInt() ;
        for(int i=0; i<N; i++)
            ts = input.nextInt() ;
            id = input.nextInt() ;
            for(int j=ts-D+1; j<=ts+D-1; j++)
                if(j>=0 && j<a[0].length && a[id][j] != 0 )
                    a[id][ts] ++ ;
                
            
            a[id][ts] ++ ;

            if(a[id][ts] >=K)
                set.add(id) ;
            
        
        Iterator iterator = set.iterator() ;
        while (iterator.hasNext())
            System.out.println(iterator.next());
        

    


方法2:排序后,尺取法

import java.util.*;

public class Main1 
    static int N, D, K ;
    static class R
        int ts, id ;
    
    public static void main(String[] args) 
        Scanner input = new Scanner(System.in) ;
        N = input.nextInt()  ;
        D = input.nextInt() ;
        K = input.nextInt() ;
        R [] rs = new R[N] ;
        for(int i=0; i<N; i++)
            R r = new R() ;
            r.ts = input.nextInt() ;
            r.id 以上是关于第九届蓝桥杯JavaB组(2018年)省赛题解的主要内容,如果未能解决你的问题,请参考以下文章

第九届蓝桥杯省赛B组 做题记录(python)

蓝桥杯赛前冲刺-枚举暴力和排序专题2(包含历年蓝桥杯真题和AC代码)

蓝桥日记②2018第九届省赛(软件类)JavaA组★答案解析

第九届蓝桥杯省赛B组 做题记录(python)

第九届蓝桥杯省赛B组 做题记录(python)

2018年第九届蓝桥杯 - 省赛 - C/C++大学B组 - F.递增三元组