Code Jam Kickstart 2019 Round A 题解

Problem A

题目

题意:

分析

直接滑动窗口解决O(n)

代码

class Solution {
public static void main(String[] args) {
        Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
        int t = in.nextInt();
        for (int num = 1; num <= t; ++num) {
            int N = in.nextInt();
            int P = in.nextInt();
            int[] S = new int[N];
            for (int j = 0; j < N; j++) {
                S[j] = in.nextInt();
            }

            int res = Integer.MAX_VALUE;
            Arrays.sort(S);
            int left = 0, right = P - 1;
            int sum = 0;
            for (int i = left; i <= right; i++) sum += S[i];
            res = Math.min(res, P * S[right] - sum);
            while (right < N) {
                sum -= S[left];
                left++;
                right++;
                if (right == N) break;
                sum += S[right];
                res = Math.min(res, P * S[right] - sum);
            }
            System.out.println("Case #" + num + ": " + res);
        }
    }
}


Problem B

题目

题意:

分析

  • 多源BFS + 二分
    • (1) 先使用多源BFS,从多个邮局出发,求出每个点到邮局的最短距离,复杂度是O(RC,然后得到了最大的距离,
      并且能够得到最大的距离max_dist即overall delivery time

    • (2) 然后使用二分搜索,能否找到一个K,在0-max_dist之间,满足如果在某处新建一个邮局,能否使得最大的delivery time(即最大的距离)至多是K
      复杂度O(RClog(R+C))
      也就是说 对于一个固定的K, 我们判断,是否可以找到一个点放置邮局使得,所有点到delivers的距离不会超过K.
      这里判断的时候还用到了个数据小技巧,就是曼哈顿距离与切比雪夫距离的转化:
      dist((x1, y1), (x2, y2)) = max(abs(x1 + y1 - (x2 + y2)), abs(x1 - y1 - (x2 - y2)))

代码

public class Solution {
    
    public static void main(String[] args) {
        Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
        int t = in.nextInt();
        for (int num = 1; num <= t; ++num) {
            int R = in.nextInt();
            int C = in.nextInt();
            String[] grid = new String[R];
            for (int i = 0; i < R; i++) {
                grid[i] = in.next();
            }
            char[][] graph = new char[R][C];
            for (int i = 0; i < R; i++) {
                for (int j = 0; j < C; j++) {
                    graph[i][j] = grid[i].charAt(j);
                }
            }
            int res = solveLarge(graph, R, C);
            System.out.println("Case #" + num + ": " + res);
        }
    }

    static int[][] dist;
    static int[][] dirs = {{1,0}, {0, 1}, {-1, 0}, {0, -1}};

    private static int solveLarge(char[][] graph, int m, int n) {
        int res = 0;
        dist = new int[m][n];
        int hi = multiBFS(graph, m, n);
        int low = 0;
        while (low <= hi) {
            int mid = (low + hi) >> 1;
            if (isValid(mid, m, n)) hi = mid - 1;
            else low = mid + 1;
        }
        res = hi + 1;
        return res;
    }

    private static int multiBFS(char[][] graph, int m, int n) {
        int maxDist = 0;
        Queue<int[]> queue = new LinkedList<>();
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                dist[i][j] = -1;
                if (graph[i][j] == '1') {
                    queue.add(new int[]{i, j});
                    dist[i][j] = 0;
                }
            }
        }
        while (!queue.isEmpty()) {
            int[] cur = queue.poll();
            maxDist = dist[cur[0]][cur[1]];
            for (int[] d : dirs) {
                int nx = cur[0] + d[0];
                int ny = cur[1] + d[1];
                if (nx < 0 || nx >= m || ny < 0 || ny >= n || dist[nx][ny] != -1) continue;
                dist[nx][ny] = maxDist + 1;
                queue.add(new int[]{nx, ny});
            }
        }
        return maxDist;
    }

    private static boolean isValid(int mid, int r, int c) {
        int x = Integer.MIN_VALUE;
        int y = Integer.MAX_VALUE;
        int z = Integer.MIN_VALUE;
        int w = Integer.MAX_VALUE;
        for(int i = 0; i < r ; ++i)
            for(int j = 0 ; j < c ; ++j)
                if(dist[i][j] > mid){
                    x = Math.max(x, i+j);
                    y = Math.min(y,i+j);
                    z = Math.max(z,i-j);
                    w = Math.min(w,i-j);
                }
        if(w == Integer.MAX_VALUE) return true;
        for(int i = 0 ; i < r; ++i)
            for(int j = 0 ; j < c; ++j)
                if(Math.abs(x - (i+j)) <= mid &&
                        Math.abs(y - (i+j)) <= mid &&
                        Math.abs(z - (i-j)) <= mid &&
                        Math.abs(w - (i-j)) <= mid)
                    return true;
        return false;
    }
}

Problem C

题目

题意:

分析

代码

posted @ 2019-05-08 15:55  shawshawwan  阅读(345)  评论(0编辑  收藏  举报