A 牛牛爱奇数

解题思路
这道题有两种解法,第一种是贪心的思路,我们每一次肯定优先将一些大的偶数先变小,让它与那些小的偶数相等之后,再统一变成奇数,而每一次选出当前最大的一个偶数当然要使用大根堆。

参考代码

import java.util.*;


public class Solution {
    /**
     * 返回一个数,代表让这些数都变成奇数的最少的操作次数
     * @param n int整型 代表一共有多少数
     * @param a int整型一维数组 代表n个数字的值
     * @return int整型
     */
    public int solve (int n, int[] a) {
        // write code here
        PriorityQueue<Integer> q = new PriorityQueue<Integer>(new Comparator<Integer>() {

            @Override
            public int compare(Integer o1, Integer o2) {
                // TODO Auto-generated method stub
                return o2 - o1;
            }
        });

        Set<Integer> set = new HashSet<Integer>();
        for(int i=0; i<n; i++){
            if(a[i] % 2 == 0 && !set.contains(a[i])){
                set.add(a[i]);
                q.add(a[i]);
            }
        }

        int cnt = 0;
        while(!q.isEmpty()){
            int tmp = q.poll();

            tmp /= 2;
            cnt += 1;

            if(!set.contains(tmp) && tmp % 2 == 0){
                set.add(tmp);
                q.add(tmp);
            }
        }

        return cnt;
    }
}

第二种解法就是我们知道,在该转化中所有出现的偶数都要做除2的操作,由于要统计最少的步数,故这里我们让每一种偶数都只除一次2,这样最终就可以统计出所需的最少的步数。

import java.util.*;


public class Solution {
    /**
     * 返回一个数,代表让这些数都变成奇数的最少的操作次数
     * @param n int整型 代表一共有多少数
     * @param a int整型一维数组 代表n个数字的值
     * @return int整型
     */
    public int solve (int n, int[] a) {
        // write code here
        Set<Integer> set = new HashSet<Integer>();

        int cnt = 0;
        for(int i=0; i<n; i++){

            while(a[i] % 2 == 0){
                if(!set.contains(a[i])){
                    cnt += 1;
                }
                set.add(a[i]);
                a[i] /= 2;
            }
        }

        return cnt;
    }
}


B 牛牛摆放花

解题思路
这道题是一个很经典的贪心,思路就是将最大的数字放到中间,然后依次将第2大和第3大的放到两边,第4大的接在第二大的后面,第5大的接在第3大的后面,按照这样的顺序最后得到的就是一个相邻差值最小的序列。

解题思路

import java.util.*;


public class Solution {
    /**
     * ​返回按照这些花排成一个圆的序列中最小的“丑陋度”
     * @param n int整型 花的数量
     * @param array int整型一维数组 花的高度数组
     * @return int整型
     */
    public int solve (int n, int[] a) {
        // write code here
        int ans = 0;

        if(n == 1) return 0;

        Arrays.sort(a);

        for(int i=0; i+2<n; i++){
            ans = Math.max(ans, a[i + 2] - a[i]);
        }
        ans = Math.max(ans, a[n-1] - a[n - 2]);
        ans = Math.max(ans, a[1] - a[0]); 

        return ans;
    }
}


C 星球游戏

解题思路
这道题是图论问题中最短路的一个经典的应用,由于的值都很大,所以想到的最短路算法肯定有spfa或者是Dijkstra, 这里写两种方法都是可以的,这里我写的是Dijkstra算法,具体的思路就是建立一个虚拟源点,它到牛牛的所有星球的距离都为0,然后从这个虚拟源点出发求到其它各个点的最短路,最终遍历一下牛妹的所有星球,找到一个最短的返回就好了。

参考代码

import java.util.*;

class Node implements Comparable<Node>{

    int t;
    long val;

    public Node(int t, long val){
        this.t = t;
        this.val = val;
    }

    @Override
    public int compareTo(Node o) {
        // TODO Auto-generated method stub
        return Long.compare(val, o.val);
    }
}


public class Solution {
    /**
     *
     * @param niuniu int整型一维数组 牛牛占领的p个星球的编号
     * @param niumei int整型一维数组 牛妹占领的q个星球的编号
     * @param path int整型二维数组 m条隧道,每条隧道有三个数分别是ui,vi,wi。ui,vi分别是隧道的两边星球的编号,wi是它们之间的距离
     * @param nn int整型 星球个数n
     * @return int整型
     */
    int N = 100010, M = 600010, max = 0x3f3f3f3f;
    int[] h = new int[N];
    int[] dist = new int[N];
    boolean[] st = new boolean[N];
    int[] e = new int[M];
    int[] ne = new int[M];
    int[] w = new int[M];
    int idx;

    void add(int a, int b, int c){
        e[idx] = b;
        w[idx] = c;
        ne[idx] = h[a];
        h[a] = idx ++;
    }

    void dijkstra(){
        Arrays.fill(dist, max);
        dist[0] = 0;

        PriorityQueue<Node> q = new PriorityQueue<Node>();
        q.add(new Node(0, 0));

        while(!q.isEmpty()){
            Node cur = q.poll();

            int t = cur.t;
            if(st[t]) continue;
            st[t] = true;

            for(int i=h[t]; i!=-1; i=ne[i]){
                int j = e[i];

                if(dist[j] > dist[t] + w[i]){
                    dist[j] = dist[t] + w[i];
                    q.add(new Node(j, dist[j]));
                }
            }
        }
    }

    public int Length (int[] a, int[] b, int[][] e, int nn) {
        // write code here
        Arrays.fill(h, -1);

        for(int i=0; i<a.length; i++){
            add(0, a[i], 0);
            add(a[i], 0, 0);
        }

        for(int[] cur : e){
            int u = cur[0];
            int v = cur[1];
            int w = cur[2];

            add(v, u, w);
            add(u, v, w);
        }

        dijkstra();

        int res = max;
        for(int i=0; i<b.length; i++) res = Math.min(res, dist[b[i]]);

        if(res == max) return -1;
        else return res;
    }
}

这次比赛打的非常不好,写一句话鼓励一下自己吧QWQ: