USACO Silver 2018 December - Convention
13 March 2025
[ algorithms , usaco , silver ]

Give this problem a try USACO Silver 2018 December - Convention.


Approach

First, the cows are sorted by their arrival times. The problem is then reformulated as determining the minimum waiting time x that allows all cows to be placed into M buses. Or in other words, what is the minimum number of busses required to allocate all cows with minimum waiting time x. Given that the waiting time function is monotonic, we can use binary search on x. For each candidate x, we verify whether it is feasible to assign the cows to M buses such that no cow’s waiting time exceeds x.


Example Code

import java.io.*;
import java.util.*;

public class Solution {
	public static boolean check(long x, long[] cows, int N, int M, int C) {
		long first = cows[0];
		int used = 1;
		int cap = 0;

		// minimum buses needed to have maximum wait time = x
		for (int i = 0; i < N; i++) {
			if (cows[i] - first > x || cap >= C) {
				first = cows[i];
				used++;
				cap = 0;
			}
			cap++; // add cow to bus
		}

		return used <= M;
	}

	// find maximum waiting time
	public static long search(long[] cows, int N, int M, int C) {
		long max = 1_000_000_001;
		long pos = max;

		for (long x = max; x >= 1; x /= 2) {
			while (check(pos - x, cows, N, M, C)) {
				pos -= x;
			}
		}

		return pos;
	}

    public static void main(String[] args) throws Exception {
        FastScanner io = new FastScanner("convention"); // usaco submission file
		// FastScanner io = new FastScanner();

		int N = io.nextInt(), M = io.nextInt(), C = io.nextInt();
		long[] cows = new long[N];
		for (int i = 0; i < N; i++) { cows[i] = io.nextLong(); }
		
		Arrays.sort(cows);

		long answer = search(cows, N, M, C);
		io.println(answer);

		io.close();
    }

    /**
        SPECIAL NUMBERS
    */
    public static int MOD = 1_000_000_007;

    /**
        DATA STRUCTURES
    */
    static class MultiSet {
        static TreeMap<Integer, Integer> multiset = new TreeMap<>();
        static void add(int x) {
            multiset.putIfAbsent(x, 0);
            multiset.put(x, multiset.get(x)+1);
        }
        static void remove(int x) {
            multiset.putIfAbsent(x, 0);
            multiset.put(x, multiset.get(x)-1);
            if (multiset.get(x) <= 0) multiset.remove(x);
        }
    }

    /**
        IO
    */
    static class FastScanner extends PrintWriter {
        private BufferedReader br;
        private StringTokenizer st;
		
		// standard input
        public FastScanner() { this(System.in, System.out); }
		public FastScanner(InputStream i, OutputStream o) {
            super(o);
			st = new StringTokenizer("");
            br = new BufferedReader(new InputStreamReader(i));
        }
		// USACO-style file input
        public FastScanner(String problemName) throws IOException {
            super(problemName + ".out");
			st = new StringTokenizer("");
            br = new BufferedReader(new FileReader(problemName + ".in"));
        }

        // returns null if no more input
        public String next() {
            try {
                while (st == null || !st.hasMoreTokens())
                    st = new StringTokenizer(br.readLine());
                return st.nextToken();
            } catch (Exception e) { }
            return null;
        }
        public int nextInt() { return Integer.parseInt(next()); }  
        public double nextDouble() { return Double.parseDouble(next()); }   
        public long nextLong() { return Long.parseLong(next()); }   
    }
}

Complexity Analysis

  • Time Complexity: O(NlogN)
  • Space Complexity: O(N)

Sign-off

Congratulations on making it this far! Best of luck in your future competitions!