集训队作业开冲。
2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15)
- B - Binary vs Decimal
- C - Cactus Jubilee
- D - Distance on Triangulation
- H - Hypercube
- I - Iceberg Orders
- J - Jump
- K - King’s Inspection
- L - Landscape Improved
B - Binary vs Decimal
题意简述
求第 $n$ 小的正整数 $A$ 满足:
- $A$ 中仅含
0
,1
。 - 设 $A$ 的二进制表示为 $B$,则 $A$ 为 $B$ 的后缀。
$n\le 10000$。
主要思路
1 | def check(i): |
然而显然这样是过不去的。
打了个表,好像也没啥性质。
后来发现如果 $A$ 合法,则 $A$ 的任意一个后缀都合法。
于是写个高精 bfs 就好了。
参考代码
1 |
|
H - Hypercube
题意简述
给三位空间上 $8$ 个单位正方体,判断它们能否折叠成一个四维超立方体。
主要思路
被教育了一个非常 nb 的做法。
四维无法想象,故先考虑把 $6$ 个小正方体折成三维立方体。
那么折成的小立方体,从某一面开始,无论沿着哪个方向走 $2$ 步就能走到其对面,再走 $2$ 步就能走回来。
考虑到实际上只有两个方向,那么不妨考虑一个面 $c$(其对面记为 $-c$)与两个映射 $f_{x, y}$,$f_i(c)$ 意为在方向 $i$ 上走一步走到的面。
那么我们有 $f_x^2(c) = f_y^2(c) = -c$。
考虑在平面上也只有两个方向,故对于两个面 $c, d$,钦定 $c$ 是折起来后的哪一面,按照 $c\to d$ 经过的路径不断映射就能得到 $d$ 是哪一面。
对于所有 $(c, d)$ 计算出 $d$ 是哪一面,当有一组 $(c, d)$ 对应的面相同,则可充分说明无解。
其必要性不难证明。
那么关于这两个映射如何设。
可以构造如下的映射,其中元组的前两维代表到该面的方向,最后一维代表是在哪一面。即两个元素相等只需最后一维相等即可。
$$
f_x(A, B, C) = (-C, B, A)\\
f_y(A, B, C) = (A, -C, B)
$$
那么回到四维的情况,就类似地需要有三个方向的映射。
$$
f_x(A, B, C, D) = (-D, B, C, A)\\
f_y(A, B, C, D) = (A, -D, C, B)\\
f_z(A, B, C, D) = (A, B, -D, C)
$$
即可。
参考代码
1 |
|
顺带一提,这个 sb 开始写了个极为复杂的实现,然后又被教育了,,,
J - Jump
题意简述
交互题,猜01
串 $S$,$|S| = n$ 为偶数。
每次可以猜一个串 $T$,若 $S,T$ 的 $n$ 位全都相等则结束。
否则,若两串恰好有 $n/2$ 位相等,返回 $n/2$;否则返回 $0$。
请在 $n + 500$ 次内猜出 $S$,$n\le 1000$。
主要思路
随机一个串使得恰有 $n/2$ 位相等,据说大概 $\sqrt{n}$ 次左右就能得到一个。
然后对于相邻两位 $i, i + 1$,将他们均取反,查一次,可以知道 $s_i\omega s_{i+1}$。
于是再来两次查询第一个位的值即可。
参考代码
1 | import random |
K - King’s Inspection
题意简述
有向图保证 $m\le n + 20, n\le 10^5$,求一条哈密顿回路,需判断无解。
主要思路
首先对于一些只有一条入边 $(v, u)$ 的点 $u$,很明显我们可以知道回路中只能 $v\to u$。
那么最后就可以压成 $O(m - n)$ 条链,这些链必须从链头走向链尾。
那么枚举一下这些链之间的顺序就好了。
复杂度是多少啊(/yun
)
参考代码
1 |
|
L - Landscape Improved
题意简述
二维搭积木,第 $i$ 列上已经搭了 $h_i$ 块。共 $n$ 个位置。
现在你手上有 $W$ 块积木,手上的积木能搭在某个位置当且仅当该位置左下、正下、右下三个位置都已经有积木。
求最高的一列能搭多高。
$n\le 10^5, h_i\le 10^9, W\le 10^{18}$。
1 | . |
以上是一个 $n=8,W=4$ 的样例,其中以#
表示原先有的积木,.
表示后来放上去的积木。
主要思路
枚举一下第 $p$ 列最高,然后二分一下高度 $lim$。
那么大概就是什么找到最大的 $i<p$ 使得 $h_i + p - i \ge lim$,然后求一下区间 $(i, p)$ 的和。
对于左边也类似。
这个显然可以转成什么 $O(n)$ 次区间加减一。
求那个东西就把 $log n$ 个线段树上的区间捞下来,然后找到第一个最大值不小于 $lim$ 的区间,再套个线段树上二分啥的就好了。
参考代码
写完之后发现不优美,实际上有许多更优美的做法(例如直接来个 ST表和树状数组)。
虽然复杂度都是 $O(n\log^2 n)$ 啦。
1 |
|