[Pro Kao 06 group 01] solution to the fourth Blue Bridge Cup JAVA group A national competition

1. Filling formula

(1) Title Description

    Please see the following formula:

    (ABCD - EFGH) * XY = 900

    Each letter represents a number from 0 to 9. Different letters represent different numbers. The first cannot be 0.

    For example, (5012 - 4987) * 36 is a solution.

    Please find another solution and submit the integer represented by ABCD in the solution.

    Please submit your answers through the browser in strict accordance with the format.
    Note: only submit the integer represented by ABCD, and do not write other additional contents, such as explanatory text.

(2) Knowledge points involved: dfs full arrangement + simple calculation
(3) Analysis and answer: this question is not difficult. If you can arrange it all, you can certainly do it. Enumerate all the possibilities, and then express the three numbers respectively. Due to the relationship of full arrangement, it doesn't matter what digit that number does. Just add it in order.
(4) Code:

Click to view the code
    public class Main04JA01 {
    
        /**
         * @param args
         */
        public static int a[]={0,1,2,3,4,5,6,7,8,9};
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            dfs(a,0);
        }
        public static void dfs(int a[],int k){
            if(k==10){
                if(check()){
                    System.out.print(a[0]*1000+a[1]*100+a[2]*10+a[3]);
                    System.out.println();
                }
            }else{
                for(int i=k;i<10;i++){
                    int temp=a[i];
                    a[i]=a[k];
                    a[k]=temp;
                    dfs(a,k+1);
                    temp=a[i];
                    a[i]=a[k];
                    a[k]=temp;
                }
            }
        }
        private static boolean check() {
            // TODO Auto-generated method stub
            int res1=a[0]*1000+a[1]*100+a[2]*10+a[3];
            int res2=a[4]*1000+a[5]*100+a[6]*10+a[7];
            int res3=a[8]*10+a[9];
            return ((res1-res2)*res3)==900&&a[0]!=0&&a[4]!=0&&a[8]!=0;
        }
    }

2. Dice puzzle

(1) Title Description

    Xiao Ming participated in an interesting activity in the children's Palace: each child was given a blank dice (its six sides were blank and had no numbers), and the children were asked to design which number to write on each side. However, there are the following requirements:

    1. Only one number from 0 to 8 can be filled in each face.

    2. Different faces can fill in the same number, but the sum of the six faces must be equal to 24.

    After filling in, the children can challenge the two robots in the children's palace with the dice they have filled in the numbers - playing the dice game. The rules are as follows:

    The three parties roll their own dice at the same time. If there is any same number, the three parties will not score.
  
    If the numbers of the three parties are different, 1 point will be deducted for the smallest number and 1 point will be added for the largest number.
   
    Xiao Ming sees the dice in the hands of two robots, which are:

    0 0 0 8 8 8
  
    1 1 4 5 6 7

    Please calculate for Xiao Ming how he can fill it in to maximize his probability of scoring.

    Please submit the six numbers Xiao Ming should fill in, arranged in ascending order, separated by a space.

    If you think there are multiple answers, submit the one with the smallest alphabetical order.

    Please submit your answers through the browser in strict accordance with the format.
    Note: submit only one line with 6 numbers separated by spaces. Do not write other additional content, such as explanatory text.

(2) Knowledge points involved: dfs + probability operation

(3) Analysis and solution: I saw pruning on the Internet. In fact, this problem is not necessary because the amount of data is very small. Even the six-layer loop enumeration is very small, so it's OK to search directly. I haven't tried the six-layer loop yet. If there's no way in the examination room, I might as well try it. Anyway, it won't timeout. What's the idea of this question? It's actually very simple. First enumerate, then compare the cases that are larger than the numbers of the two robots as long as they meet the conditions, and then multiply them. In fact, the two numbers should be divided by 6 respectively, but there is no need to increase the difficulty because the maximum probability result is not required.

(4) Code:

Click to view the code
 public class Main04JA02 {
    
        /**
         * @param args
         */
         static int a[]={0,0,0,8,8,8};
         static int b[]={1,1,4,5,6,7};
         static int c[]=new int[6];
         static int res[]=new int[6];
         static int max=0;
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            dfs(0,0,0);
            for(int i=0;i<6;i++){
                System.out.print(res[i]+" ");
            }
            System.out.println();
        }
        public static void dfs(int n,int cur,int sum){
            if(sum>24){
                return;
            }
            if(n==6){
                if(sum==24){
                    count();
                }
                return;
            }
            for(int i=cur;i<9;i++){
                c[n]=i;
                dfs(n+1,i,sum+i);
                c[n]=0;
            }
        }
        private static void count() {
            // TODO Auto-generated method stub
            int m=0;int x1=0;int x2=0;
            for(int i=0;i<6;i++){
                x1=x2=0;
                for(int j=0;j<6;j++){
                    if(c[i]>a[j]){
                        x1++;
                    }
                }
                for(int j=0;j<6;j++){
                    if(c[i]>b[j]){
                        x2++;
                    }
                }
                m+=x1*x2;
            }
            if(m>max){
                for(int i=0;i<6;i++){
                    res[i]=c[i];
                }
                max=m;
            }
        }
    }

3. Egypt score

(1) Title Description

        Ancient Egypt once created a splendid human civilization, but their scores are very puzzling. Ancient Egypt liked to decompose a fraction into a format similar to: 1/a + 1/b.
    
        Here, a and b must be two different integers, and the numerator must be 1
    
        For example, there are four different decomposition methods for 2 / 15 (referred to as Egyptian decomposition method for the moment):
    
        1/8 + 1/120
           1/9 + 1/45
            1/10 + 1/30
        1/12 + 1/20
    
    
        So, how many different Egyptian decompositions are there in 2 / 45? Please submit the integer directly (never submit a detailed decomposition!).
    
        Please submit your answers through the browser in strict accordance with the requirements.
        Note: only submit the number of categories decomposed, and do not write other additional contents, such as explanatory text

(2) Knowledge points involved: double precision operation + violent enumeration

(3) Analysis and solution: at first glance, this question is very simple, but when you encounter this kind of problem in the national competition, you must have a long mind. There may be some traps behind it. In fact, you can see how the third question in group A of the national competition can produce a problem that beginners can do. This question is very tricky. Where is the tricky? At the beginning, I used (double) 1/i+(double)1/j==(double)2/45. In order to be safe, I specially measured the answer of 2 / 15. The answer of 2 / 15 happened to be right, but it was wrong to change the answer to 2 / 45. In fact, I don't know the specific reason. My only understanding is that double has only 14 decimal places, so the calculation is not so accurate, Of course, I won't eliminate the error, so here's another way. What shall I do? In fact, division is not accurate, but multiplication is certainly accurate. Therefore, I suggest that multiplication should not be used as much as possible. Therefore, what we need to do here is to divide the same score and convert it into Multiplication 45*j+45*i=2*i*j. in fact, the double type is not required, and the int type is OK.

(4) Code:

Click to view the code
    public class Main04JA03 {
    
        private static int ans;
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            for(double i=1;i<=10000;i++){
                for(double j=i+1;j<=10000;j++){
                    if((double)45*j+45*i==(double)2*i*j){
                        System.out.println(i+" "+j);
                        ans++;
                    }
                }
            }
            System.out.println(ans);
        }
    
    }

4. Approximate multiple selection card

    (1) Title Description

      In their spare time, Holmes and Watson play a game:
        
        Write n integers on N cards. The two took turns to take a card. It is required that the number taken by the next person must be a divisor or multiple of the number taken by the previous person. For example, once Holmes took the card with the number "6", the next numbers Watson can take include:
    
        1,2,3, 6,12,18,24 ....
    
        When it's a party's turn to take the card, if there is no card that meets the requirements, the party is the loser.
    
        Please make use of the advantages of the computer to calculate how to choose to ensure victory when you know the numbers on all cards and which numbers to choose!
    
        When multiple numbers are selected to win, the smallest number is output. If you lose anyway, output - 1.
    
    
        The input data is 2 rows. The first line is an integer separated by several spaces (each integer is between 1 and 100), representing all the remaining cards.
        The second line is also an integer separated by several spaces, indicating the optional numbers. Of course, the number in the second line must be completely included in the number in the first line.
    
        The program outputs the winning moves!!
    
    
    For example:
    User input:
    2 3 6
    3 6
    The program should output:
    3
    
    Another example:
    User input:
    1 2 2 3 3 4 5
    3 4 5
    The program should output:
    4
    
    
    Resource agreement:
    Peak memory consumption (including virtual machine) < 64M
    CPU consumption  < 2000ms
    
    
    Please output in strict accordance with the requirements, and do not print superfluous contents such as "please input...".
    
    All code is placed in the same source file. After debugging, the copy is submitted to the source code.
    Note: do not use package statements. Do not use features of jdk1.6 and above.
    Note: the name of the Main class must be: Main, otherwise it will be treated as an invalid code.

(2) Knowledge points involved: Game Theory + dfs

(3) Analysis and answer: I'm not very good at the topic of game theory. After all, I haven't learned it systematically. I can only use someone else's code to explain my ideas. The idea of game theory of this problem is probably like this. Let's look back at the input. The input data is 2 lines. The first line is an integer separated by several spaces (each integer is between 1 and 100), representing all the remaining cards. The second line is also an integer separated by several spaces, indicating the optional numbers. Of course, the number in the second line must be completely included in the number in the first line. The program outputs the winning moves!!
So what if you don't have any ideas? After confirming the knowledge points, we went back to the title without thinking and analyzed what the title asked us to do step by step. A common problem of many contestants is that they often take the title for granted, so the details in the title will be ignored. This provincial competition is a good lesson. We can see that there is a sentence in the title that when it's a party's turn to take the card, there are no cards that meet the requirements, Then this party is the loser. Moreover, there is not only one card for each card, so it can be clearly confirmed that the number must be recorded with the array subscript. The second line is the subsequent scheme. What can we think of here if we choose the scheme that we are sure to win? Go ahead and try it all again. Finally, look at the result. What algorithm is it? It's only dfs.
After grasping the knowledge points, we will start to design algorithms. It is not difficult for dfs to think of what to search. Every time I think of dfs, I can't think of what to search, which is very desperate. Therefore, to grasp the meaning of the title, the time for the national competition should be enough. Four hours. Generally, the first three questions don't take much time, It's enough to do two questions in the next two or three hours, so calm down and think. The computer test is not only about problem-solving ability, but also psychological quality. If the last question can be scored by violence, it's OK. In this way, there must be no problem for Guoyi, except for the big guys. Far from it, what is dfs going to search for? Is it to search for a certain winning scheme? Where can we find all the schemes? Then we can create a linked list array and store all the schemes. Here, we must pay attention to putting them back, otherwise we can't list all the schemes. Finally, we can search all the schemes according to the cards I take, Until all the cards are taken, you don't have to put them back here. Ha ha, otherwise you can't play until you die.

(4) Code:

Click to view the code
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Scanner;
    
    public class Main04JA04 {
    
        /**
         * @param args
         */
        static int[]num=new int[105];
        static ArrayList<Integer>g[]=new ArrayList[105];
        static ArrayList<Integer>choice=new ArrayList<>();
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner scan=new Scanner(System.in);
            String[]s1=scan.nextLine().split(" ");
            String[]s2=scan.nextLine().split(" ");
            for(int i=0;i<=100;i++){
                g[i]=new ArrayList<>();
            }
            for(String s:s1){
                if(!s.equals("")){
                    num[Integer.parseInt(s)]++;
                }
            }
            for(String s:s2){
                if(!s.equals("")){
                    choice.add(Integer.parseInt(s));
                }
            }
            for(int i=1;i<=100;i++){
                if(num[i]>0){
                    num[i]--;
                    for(int j=1;j<=100;j++){
                        if(num[j]>0&&(i%j==0||j%i==0)){
                            g[i].add(j);
                        }
                    }
                    num[i]++;
                }
            }
            
            int flag=-1;
            Collections.sort(choice);
            for(int x:choice){
                num[x]--;
                if(dfs(x)==1){
                    flag=x;
                    break;
                }
                num[x]++;
            }
            System.out.println(flag);
        }
        private static int dfs(int u) {
            // TODO Auto-generated method stub
            for(int i=g[u].size()-1;i>=0;i--){
                int v=g[u].get(i);
                if(num[v]>0){
                    num[v]--;
                    int win=dfs(v);
                    num[v]++;
                    if(win==1){
                        return -1;
                    }
                }
            }
            return 1;
        }
    
    }

5. Network routing

(1) Title Description

        A network in country X uses several lines to connect several nodes. The communication between nodes is bidirectional. For the sake of security, an important packet must be forwarded exactly twice to its destination. The packet may be generated at any node. We need to know how many different forwarding paths there are in the network.
    
        The source address and destination address can be the same, but the intermediate node must be different.
    
        The network shown in Figure 1.
    
        1 -> 2 -> 3 -> 1   Yes
        
        1 - > 2 - > 1 - > 2 or 1 - > 2 - > 3 - > 2 are illegal.
    
        The first line of the input data is two integers N M, which respectively represent the number of nodes and the number of connecting lines (1 < = n < = 10000; 0 < = m < = 100000).
        Next, there are M lines. Each line has two integers u and v, indicating that nodes u and v are connected (1 < = u, v < = n, u! = v).
    
        The input data ensures that at most one edge of any two points is connected, and there is no self connected edge, that is, there is no double edge and self ring.
    
    
        Output an integer indicating the number of paths that meet the requirements.
    
    For example:
    User input:
    3 3
    1 2
    2 3
    1 3
    The program should output:
    6

(2) Knowledge points involved: undirected graph construction + dfs

(3) Analysis and answer: this year's topic is the search topic. I guess it's the fourth one. I'm not proficient. There are 6 questions in total, 4 questions for DFS, 1 question for double precision operation and 1 question for number theory. It can be seen that DFS is still very important in the blue Bridge Cup, so I must master it skillfully. In fact, this problem is simpler than the previous one. As long as you build an undirected graph and search each point, and the simplest thing about this problem is that the route is fixed and can only be two times. Then you can take three steps. You can't go through the points in the middle or go back to the starting point to do it again. Then you can use the access tag array, It is simple to add no double edges and self rings.

(4) Code:

    import java.util.ArrayList;
    import java.util.Scanner;
    
    public class Main04JA05 {
        static int n,m,ans=0;
        static ArrayList<Integer>[]g;
        static boolean[]vis;
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner scan=new Scanner(System.in);
            n=scan.nextInt();
            m=scan.nextInt();
            g=new ArrayList[n+5];
            vis=new boolean[n+5];
            for(int i=0;i<=n;i++){
                g[i]=new ArrayList<>();
            }
            for(int i=1;i<=m;i++){
                int a=scan.nextInt();
                int b=scan.nextInt();
                g[a].add(b);
                g[b].add(a);
            }
            for(int i=1;i<=n;i++){
                dfs(i,-1,3);
            }
            System.out.println(ans);
            
        }
        private static void dfs(int u, int fa, int step) {
            // TODO Auto-generated method stub
            if(step==0){
                ans++;
                return;
            }
            for(int v:g[u]){
                if(!vis[v]&&v!=fa){
                    vis[v]=true;
                    dfs(v,u,step-1);
                    vis[v]=false;
                }
            }
        }
    
    }

6. Formula evaluation

(1) Title Description

        Input n, m, k and output the value of the formula shown in Fig. 1. Where C_n^m is the combination number, which represents the number of schemes in which m people are selected from the set of n people to form a set. The calculation formula of combination number is shown in Figure 2.
    
        The first line of input contains an integer n; The second line contains an integer m and the third line contains an integer k.
    
        Calculate the value of the formula shown in Figure 1. Since the answer is very large, please output the remainder of this value divided by 999101.
    
    [example input 1]
    3
    1
    3
    [sample output 1]
    162
    
    [example input 2]
    20
    10
    10
    [sample output 2]
    359316
    
    [data scale and agreement]
    For 10% data, n ≤ 10, k ≤ 3;
    For 20% data, n ≤ 20, k ≤ 3;
    For 30% data, n ≤ 1000, k ≤ 5;
    For 40% data, n ≤ 10 ^ 7, k ≤ 10;
    For 60% data, n ≤ 10 ^ 15, k ≤ 100;
    For 70% data, n ≤ 10 ^ 100, k ≤ 200;
    For 80% data, n ≤ 10 ^ 500, k ≤ 500;
    For 100% data, n does not exceed 1000 bits in decimal system, i.e. 1 ≤ n < 10 ^ 1000, 1 ≤ k ≤ 1000, and 0 ≤ m ≤ n, k ≤ n.
    
    [prompt]
    999101 is a prime number;
    When there are many n digits, the answer is 0 in most cases, but some data whose answer is not 0 will be selected during evaluation;
    
    Resource agreement:
    Peak memory consumption (including virtual machine) < 128M
    CPU consumption  < 2000ms
    
    
    Please output in strict accordance with the requirements, and do not print superfluous contents such as "please input...".
    
    All code is placed in the same source file. After debugging, the copy is submitted to the source code.
    Note: do not use package statements. Do not use features of jdk1.6 and above.
    Note: the name of the Main class must be: Main, otherwise it will be treated as an invalid code.


(2) Knowledge points involved: number theory related knowledge

(3) Analysis and solution: I can't understand this question for a while. After all, I haven't learned much about number theory. I attach the big guy code (90% pass rate)

https://blog.csdn.net/u010836847/article/details/21166725?utm_source=copy

(4) Code:

Click to view the code
   import java.math.BigInteger;
    import java.util.Scanner;
     
    public class Main04JA06 {
        /***
         * @author Lin Fan
         */
        public static BigInteger lucas(BigInteger n,BigInteger m,BigInteger p){
            if(m.equals(BigInteger.ZERO)) return BigInteger.ONE;
            return BigInteger.valueOf(f(n.mod(p).longValue(),m.mod(p).longValue())).multiply(lucas(n.divide(p),m.divide(p),p)).mod(p);
        }
     
        public static long f(long n,long m){
            if(m>n) return 1;
            if(n==m|| m==0) return 1;
            if(m>n-m) m=n-m;
            long tmpi=1,tmpn=1,s1=1,s2=1,ans=1;
            for (int i = 1; i<=m; i++) {
                tmpi=i;
                tmpn=n-i+1;
                s1=s1*tmpi%999101;
                s2=s2*tmpn%999101;
            }
            ans = s2*pow1(s1,999099)%999101;
            return ans%999101;
        }
        public static long pow1(long x,long n) {
            if(x==1) return 1;
            if (n==0)
                return 1;
            else {
                while ((n & 1)==0) {
                    n>>=1;
                    x=(x *x)%999101;
                }
            }
            long result = x%999101;
            n>>=1;
            while (n!=0) {
                x=(x *x)%999101;;
                if ((n & 1)!=0)
                    result =result*x%999101;
                n>>=1;
            }
            return  result;
        }
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            BigInteger n = new BigInteger(sc.nextLine());
            BigInteger m = new BigInteger(sc.nextLine());
            int k = Integer.parseInt(sc.nextLine());
            long start = System.currentTimeMillis();
            BigInteger md = new BigInteger("999101");
            long Cnm=lucas(n, m,md).longValue()%999101;
            long sum = 0;
            if(Cnm!=0){
                int[][] a = new int[k][k];
                int h = 1;
                for (int i = 0; i < k; i++) {
                    for (int j = 0; j < k; j++) {
                        if (j >= h)
                            a[i][j] =0;
                        else {
                            if (j == 0 || j == h - 1)
                                a[i][j] = 1;
                            else {
                                a[i][j] = (a[i - 1][j - 1]*(h - j)+a[i - 1][j])%999101;
                            }
                        }
                    }
                    h++;
                }
                long m1 = 1,n1 =1;
                long x=n.subtract(new BigInteger(k+"")).mod(md.subtract(BigInteger.ONE)).longValue();
                long n3 = pow1(2,x);
                for (int i = k - 1; i >= 0; i--) {
                    n1=n3*pow1(2,i)%999101;
                    m1 = m1*(n.subtract(new BigInteger((k - 1 - i) + "")).mod(md).longValue())%999101;
                    sum = (sum+m1*a[k - 1][i]*n1)%999101;
                }
                sum = sum*Cnm%999101;
            }
            System.out.println(sum);
            long end = System.currentTimeMillis();
            System.out.println(end - start);
        }
     
    } 

 

Posted by Or1g1naL on Wed, 01 Dec 2021 04:37:47 -0800