# Code Jam Kickstart 2019 Round A 题解

## Problem A

### 代码

class Solution {
public static void main(String[] args) {
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) {
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;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
dist[i][j] = -1;
if (graph[i][j] == '1') {
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;
}
}
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编辑  收藏  举报