Atcoder-ABC376

-
-
2024-10-20

C. 题目链接

思路:对a和b排序,然后二分答案。check函数主要逻辑是将mid放在哪个位置更好,以及能不能把所有球给装完。

算法标签:二分答案、贪心。

时间复杂度:O(NLogN)

static boolean check(long mid, long[] a, long[] b) {
        int n = a.length;
        int i = 0, j = 0;
        boolean vis = false;
        for (i = 0; i < n; i++) {
            if (j == n - 1) {
                // 如果mid用过,或者a后面还有很多数字,或者mid < a[i]那么为false
                if (vis || i < n - 1 || mid < a[i]) return false;
                vis = true;
                continue;
            }
            if (a[i] > b[j]) {
                return false;
            }
            // 使用mid
            if (!vis && mid >= a[i] && mid <= b[j]) {
                vis = true;
                continue;
            }
            j++;
        }
        return i == n;
    }

    public static void solve() throws IOException {
        int n = in.nextInt();
        long[] a = new long[n];
        long[] b = new long[n-1];
        for (int i = 0; i < n; i++) {
            a[i] = in.nextLong();
        }
        for (int i = 0; i < n - 1; i++) {
            b[i] = in.nextLong();
        }
        Arrays.sort(a);
        Arrays.sort(b);
        long l = 1;
        long r = (long) 2e14;
        while (l < r) {
            long mid = l + r >> 1;
            if (check(mid, a, b)) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        if (!check(l, a, b)) {
            out.println(-1);
            return;
        }
        out.println(l);
    }

    static boolean MULTI_CASE = false;

    public static void main(String[] args) throws Exception {
        int T = MULTI_CASE ? in.nextInt() : 1;
        while (T-- > 0) {
            solve();
        }
        out.close();
    }

D. 题目链接

思路:题目是在有向图无权图求一个包含顶点1的最小的环。将两个点之间的权值看作1,然后一个包含顶点1的最小环其实可以变成一个最短路问题,假设u→v,这个v是1,我们可以把这个v看作0,题目就变成了求1到0的最短路,直接套dijkstra就行了。

算法标签:图论、最短路。

时间复杂度:O(NLogN)

public static void solve() throws IOException {
        int n = in.nextInt();
        int m = in.nextInt();
        List<int[]>[] g = new List[n + 10];
        Arrays.setAll(g, v -> new ArrayList<>());
        for (int i = 0; i < m; i++) {
            int u = in.nextInt();
            int v = in.nextInt();
            if (v == 1) {
                v = 0;
            }
            g[u].add(new int[]{v, 1});
        }
        int[] dist = new int[n + 1];
        dijkstra0(1, 0, g, dist);
        out.println(dist[0] == Integer.MAX_VALUE ? -1 : dist[0]);
    }

    static void dijkstra0(int start, int end, List<int[]>[] g, int[] dist) {
        Arrays.fill(dist, Integer.MAX_VALUE);
        PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> Long.compare(a[1], b[1]));
        boolean[] vis = new boolean[g.length];
        pq.offer(new int[]{start, 0});
        dist[start] = 0;
        while (!pq.isEmpty()) {
            int[] p = pq.poll();
            int u = p[0];
            if (u == end) return;
            if (vis[u]) continue;
            vis[u] = true;
            for (int[] next : g[u]) {
                int v = next[0], w = next[1];
                if (dist[u] + w < dist[v]) {
                    dist[v] = dist[u] + w;
                    pq.offer(new int[]{v, dist[v]});
                }
            }
        }
    }

梅狸猫
meilicat
公告

随便看看就好~