Educational Codeforces Round 70 题解

也还是非常失败的一场比赛。。。

A

题目大意:你有一些技能点,同时你有两个属性,可以用一个技能点换取一个属性上升一点。问用完技能点的前提下有多少种方案可以让你第一个属性比第二个高。

二分出最小的 $i$ 使得第一个属性值 $+i>$ 第二个属性值,然后答案就是总技能点数 $-i+1$。

B

题目大意:一个龙有 $x$ 个头,有 $n$ 个招式,分别可以打掉 个头,如果打完后头的数量大于 $0$ 就会长出 个头。问最少用多少次招式可以打完所有的龙头。

麻烦的贪心。注意最后一击要用最大的 去打,被这个坑了两次 WA。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void solve(){
while (T--){
n = read(), x = read();
int maxi = 0;
for (int i = 1; i <= n; ++i)
d[i] = read(), h[i] = read(), maxi = max(maxi, d[i]);
if (maxi >= x){
printf("1\n");
continue ;
}
bool flag = false;
for (int i = 1; i <= n; ++i)
if (h[i] < d[i]) flag = true;
if (!flag){
printf("-1\n");
continue ;
}
int ans = INT_MAX;
for (int i = 1; i <= n; ++i){
if (h[i] >= d[i]) continue;
int t = d[i] - h[i];
ans = min(ans, 2 + (x - maxi - 1) / t);
}
printf("%d\n", ans);
}
}

C

题目大意:给定一个 01 串,设 $f(l, r)$ 为串 $[l, r]$ 转为十进制时的数。求满足 $r-l+1=f(l, r)$ 的子串数目。

预处理出所有 1 之前 0 的个数,记 $i$ 位置的答案为 $bef[i]$。从 1 到 $\log n$ 枚举长度,然后枚举子串,如果 $[l, r]$ 的最高位是 1 那么判定 $r - l + 1 \le f(l, r)\le r - l + 1 + bef[l]$,是 true 就令答案加一。

这么做是因为可以认为只有开头是 1 的子串才是有意义的。这样的话只有长度不超过 $\log n$ 的子串才有可能成为答案。

(下面当时没做出来)

D

题目大意:给定一个有向图,求一种最小颜色种数的染色方案,使得没有单色环存在。

先用 Tarjan 判定是否存在环。如果不存在就全部置为 1。

然后就是玄学猜测:只需要两种颜色就可以染完整个图。这个时候可以考虑 DFS 树。

当然有一种更简单神奇的做法:只需要将所有从大标号的点指向小标号的点的边染成 2,其他染成 1 即可。因为如果存在环,环上必然存在这两种边。

E