Analysis of the real problem of the 9th Blue Bridge Cup group A (2018) provincial competition

Posted by michaelphipps on Mon, 24 Jan 2022 00:33:18 +0100

Analysis of the real problem of the 9th Blue Bridge Cup group A (2018) provincial competition

1. Score

  • 1/1+1/2+1/4+1/8+1/16+...
  • Each item is half of the previous item. If there are 20 items in total, how much is the sum
  • The results are expressed in fractions, similar to:
  • 3 / 2. Of course, the first two items are added. The numerator and denominator require mutual prime,
  • The submitted scores are the scores that have been assigned.

Idea: find the numerator and denominator and divide by the maximum common divisor.

/**
 * 1.fraction
 * 1/1+1/2+1/4+1/8+1/16+...
 * Each item is half of the previous item. If there are 20 items in total, how much is the sum
 * The results are expressed in fractions, similar to:
 * 3/2,Of course, the first two items are added. The numerator and denominator require mutual prime,
 * The submitted scores are the scores that have been assigned.
 */
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. Monday
Idea: make a leap year judgment, accumulate the number of days, and then divide by 7 to get the number of days on Monday.

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. Complex power
Idea: you need to use BigInteger unique to Java, and then iteratively find out the imaginary part and real part.

import java.math.BigInteger;

/**
 * 3.Complex power
 * Let i be the imaginary unit. For any positive integer n, the real and imaginary parts of (2+3i)^n are integers,
 * Find how much (2+3i)^123456 equals. This number is very large and requires accurate representation,
 */
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. Square counting
Idea: find a quadrant that meets the limiting conditions and multiply by 4.

 * 4.Grid count
 */
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. Fill in the blank with code: omitted

6. Flight date
Thought: law problem, the sum of the time difference between two voyages and the average is the sailing time.

 * 4.Grid count
 */
/**
 * Flight date
 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. Three body attack
Thought: I use the violence method, which can pass some test cases. The better method is two points plus three-dimensional prefix and, but it is reliable to score quickly with violence on the field.

import java.util.Scanner;

/**
 * 7.Three body attack
 *
 */
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] ; //Used to store the health of each warship
        attack = new int [m][7] ;//Record 7 data for each round of attack
        for(int i=1; i<=A; i++){ //Record the health of the warship
            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++){ //Record attack information
            for(int j=0; j<7; j++){
                attack[i][j] = input.nextInt() ;
            }
        }
        for(int round=0; round<m; round++){ //Number of attack rounds
            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){ //HP reduced when attacked
                            a[i][j][k] -= attack[round][6] ;
                        }else{ //If HP is less than 0, it will explode
                            System.out.println(round+1);
                            return ;
                        }
                    }
                }
            }
        }
    }
}

8. Global warming
Idea: Search + tag
The first round of search calculates how many islands there are;
Then the iterative traversal will not be drowned out
The second round found the number of islands that would not be submerged
Subtracting the results of the two rounds of search is the number of submerged islands

import java.util.Scanner;

/**
 * 8.global warming
 */

/**
 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 ++ ;//Calculate the number of islands
                }
            }
        }
        for(int i=1; i<N-1; i++) { //Those that have not been submerged are marked as#
            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 ++ ;//Calculate the number of islands not submerged
                }
            }
        }
        System.out.println(cnt-cnt1); //Number of submerged Islands
    }

    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. Multiple problem
Method 1: violence enumeration
Three layer loop, enumerating from large to small. The test case data is not very large and can pass most test cases.

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

/**
 * 9.Multiple problem
 *
 */
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--){ //Can pass 60% of test cases
            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);
                    }
                }
            }
        }

    }
}

Method 2: sort + search
Sort from large to small, search enumeration, and end when the first one is found

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

/**
 * Sort from small to large, and then search for enumerations
 */
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. Payment issues
Idea: greedy strategy, the money you own is sorted from small to large. If the money you own is less than the average share value every time, you will give it all. Otherwise, if everyone gives the average share value, it will be locally optimal and globally optimal.

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));
    }
}

Topics: Java Algorithm