zoukankan      html  css  js  c++  java
  • 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

    题目

    题意:

    分析

    代码

  • 相关阅读:
    基于udp简单聊天的系统
    网络编程_tcp与dup协议简单应用
    logging_modules
    linux内核配置与编译
    linux内核简介
    对于国嵌上学期《一跃进入C大门》Mini2440的代码修正
    通过按键玩中断
    MMU功能解析、深入剖析、配置与使用
    C与汇编混合编程
    一跃进入C大门
  • 原文地址:https://www.cnblogs.com/shawshawwan/p/10832401.html
Copyright © 2011-2022 走看看