JD 2017 school recruitment programming question - Security Scheme (number of mountain pairs)

Posted by kiranoleti on Thu, 02 Jan 2020 09:43:39 +0100

JD 2017 school recruitment programming question - Security Scheme (number of mountain pairs)

Title Link

subject


In short:

For a circular mountain range, which two mountains can see each other's beacon fire, the conditions are as follows:

  • (1) Adjacent mountains;
  • (2) There is no mountain (can be equal) larger than the minimum value of the two mountains in the middle of a road between the two mountains;

Give the value of crater array, and find the logarithm of mountains that can be seen by each other

analysis

The solution process is as follows:

  • First, prepare a stack, in which the peak value and the number of times of the mountain are stored, from the bottom of the stack to the top according to the peak value from large to small;
  • First find the first largest value in the array and start traversing, traversing a circle of mountain array;
  • If the current value is larger than the top of the stack, the current top of the stack should be released and the top of the stack should be settled, which can be divided into three situations as shown in the lower right corner of the figure below;
  • If it is equal, count the number of times, times + +, if < and has not appeared, add it;
  • Finally, the stack is processed separately after traversal;

import java.io.BufferedInputStream;
import java.util.Scanner;
import java.util.Stack;

/**
 * For a circular mountain range, which two mountains can see each other's beacon fire, the conditions are as follows:
 *          (1)Adjacent mountains
 *          (2)In the middle of a road between two mountains, there is no mountain larger than the minimum value of the two mountains (can be equal)
 *  Give the value of crater array, and find the logarithm of mountains that can be seen by each other
 */
public class MountainsAndFlame { //Change to Main when submitting

    //Structure in monotone stack
    private static class Pair{
        public int value;
        public int times;

        public Pair(int value) {
            this.value = value;
            this.times = 1;  //1 is added for the first time in the stack, later++
        }
    }

    //Returns the next position in the array in the torus
    public static int nextIndex(int index,int n){
        return index < n-1 ? index + 1 : 0;
    }

    //C(2,k)
    public static long getInternalSum(int k){
        return k == 1L ? 0 : (long)k * (long)(k-1) / 2L;
    }

    //Find the mountain right
    public static long communications(int[] arr){
        if(arr == null || arr.length < 2)return 0;
        int maxIndex = 0; //Find the subscript of the maximum value first
        for(int i = 0; i < arr.length; i++) maxIndex = arr[maxIndex] < arr[i] ? i : maxIndex;
        long res = 0; //Result
        Stack<Pair>stack = new Stack<>();
        stack.push(new Pair(arr[maxIndex]));    //Push the maximum value found onto the stack to start the process
        for(int i = nextIndex(maxIndex,arr.length); i != maxIndex; i = nextIndex(i,arr.length)){ //i is the next maxIndex

            while(!stack.isEmpty() && stack.peek().value < arr[i]){
                int times = stack.pop().times;
                res += getInternalSum(times) + times * 2; //At this time, the stack cannot be empty because the maximum value is at the bottom
            }
            //Judge whether to push in or add times
            if(!stack.isEmpty() && arr[i] == stack.peek().value){
                stack.peek().times++;
            }else {
                stack.push(new Pair(arr[i]));
            }

        }
        //Processing elements in the stack separately
        while(!stack.isEmpty()){
            int times = stack.pop().times;
            res += getInternalSum(times); //Anyway, first add the internal C(2,times)
            if(!stack.isEmpty()){
                res += times;
                if(stack.size() > 1){  //> 2 levels.
                    res += times;
                }else { // <=2 level
                    res += stack.peek().times > 1 ? times : 0;
                }
            }
        }
        return res;
    }

    public static void main(String[] args) {
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        while(cin.hasNext()) {
            int n = cin.nextInt();
            int[] arr = new int[n];
            for (int i = 0; i < n; i++) {
                arr[i] = cin.nextInt();
            }
            System.out.println(communications(arr));
        }
        cin.close();
    }

}

Topics: Java Programming