前言
整体评价
VP了这场比赛, 看了下排行榜,感觉T3过的人有点少。以为很难,然后自己做的时候,感觉是卡常了。
T3用了不少小技巧做了优化,最后终于过了,撒花。
A. 简单数对推理
思路: 模拟
因为一个pair(a, b), 不是a,就是b
所以简单判定一下即可
a, b = list(map(int, input().split()))
c, d = list(map(int, input().split()))
if a == c or a == d:
print (a)
else:
print (b)
B. 平均成绩
思路:
python3的round很特别
不是严格意义上的四舍五入,而是四舍六入五平等
所以这边采用
floor(x + 0.5)
通过+0.5,然后floor来平衡
from math import floor
n = int(input())
arr = list(map(int, input().split()))
s = sum(arr)
arr.sort()
res = 0
for i in range(n):
avg = int(floor(s/n+0.5))
if avg == 5:
break
s += (5 - arr[i])
res += 1
print (res)
C. 聚会
思路: 多源BFS + 卡常优化
其实整体思路很简单,因为种类最多100,因此从种类角度出发。
构建每个种类的,每个点的最小代价(路径)
然后求每个点的s个最小代价和
因此就是
多源 B F S 多源BFS 多源BFS
但是这里面其实有两个优化点
-
多种类多源整体BFS
因为BFS保证递增,所以额外带来了好处是线性完成了前s项统计,避免了最后的sort操作
-
队列容器预分配(避免动态分配)
Deque<int[]> deq = new ArrayDeque<>();
// => 避免了动态扩容,当队列元素很多时,优化还是挺大的
Deque<int[]> deq = new ArrayDeque<>(n * k);
代码
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
AReader sc = new AReader();
int n = sc.nextInt(), m = sc.nextInt();
int k = sc.nextInt(), s = sc.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt() - 1;
}
List<Integer>[]g = new List[n];
Arrays.setAll(g, x->new ArrayList<>());
for (int i = 0; i < m; i++) {
int u = sc.nextInt() - 1, v = sc.nextInt() - 1;
g[u].add(v);
g[v].add(u);
}
int inf = Integer.MAX_VALUE / 10;
int[][] opt = new int[n][k];
for (int i = 0; i < n; i++) {
Arrays.fill(opt[i], inf);
}
long[] res = new long[n];
int[] cnt = new int[n];
Deque<int[]> deq = new ArrayDeque<>(n * k);
for (int i = 0; i < n; i++) {
deq.offer(new int[] {i, arr[i]});
opt[i][arr[i]] = 0;
cnt[i]++;
}
// 多源
while (!deq.isEmpty()) {
int[] cur = deq.poll();
int u = cur[0], t = cur[1];
for (int v: g[u]) {
if (opt[v][t] > opt[u][t] + 1) {
opt[v][t] = opt[u][t] + 1;
deq.offer(new int[] {v, t});
if (++cnt[v] <= s) {
res[v] += opt[v][t];
}
}
}
}
System.out.println(Arrays.stream(res).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
}
static
class AReader {
private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
private StringTokenizer tokenizer = new StringTokenizer("");
private String innerNextLine() {
try {
return reader.readLine();
} catch (IOException ex) {
return null;
}
}
public boolean hasNext() {
while (!tokenizer.hasMoreTokens()) {
String nextLine = innerNextLine();
if (nextLine == null) {
return false;
}
tokenizer = new StringTokenizer(nextLine);
}
return true;
}
public String nextLine() {
tokenizer = new StringTokenizer("");
return innerNextLine();
}
public String next() {
hasNext();
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
// public BigInteger nextBigInt() {
// return new BigInteger(next());
// }
// 若需要nextDouble等方法,请自行调用Double.parseDouble包装
}
}