非传统题选讲 #1

下一辑:https://www.cnblogs.com/XiaoShanYunPan/p/18870366

尚未完工,全力更新中。


正文


A

交互题。

来源:CF1634D。

题目链接

  • 简要题意:

在长度为 \(n\) 的未知序列 \(a\) 中有 恰好 一个 \(0\),你可以进行 \(2n-2\) 次询问,每次询问给出互不相同的 \(x,y,z\),询问 \(a_x,a_y,a_z\) 中最大值减去最小值的结果。

你的目标是找出 \(0\) 所在的位置,但由于你并不总能确定唯一的结果,你可以给出两个候选答案,只要其中有一个答案正确即可。

数据范围:\(4\le n\le 1000\)\(0\le a_i\le 10^9\)


  • 解法:

考虑边界情况,在 \(n=4\) 时,我们可以询问全部的 \(4\) 种本质不同的询问,然后由于这题不可能无解,我们一定有办法排除两个位置。

这就意味着,我们始终可以通过 \(4\) 次询问排除 \(2\) 个非答案的位置,于是我们只需要进行 \(4\) 次询问就可以把问题规约到 \(n-2\) 的子问题。

不难发现,在 \(n\) 为偶数时,这样的规约只会进行 \(\dfrac{n}{2}-1\) 次,于是总询问次数是 \(2n-4\) 的,而 \(n\) 为奇数的情况可以重复利用某个位置进行规约,这样的询问次数是 \(2n-2\) 的。

对于询问 \(4\) 次排除 \(2\) 个位置的讨论,注意到一定存在 \(2\) 个询问同时包含了这 \(4\) 个数中的最大值和最小值,我们任意找出 \(2\) 个结果相同且均为所有询问中最大值的询问,取其交集保留即可。

思考题:你能否在 \(\lceil\dfrac{3}{2}n\rceil\) 次询问中得到结果?


B

交互题。

来源:CF1838F。

题目链接

  • 简要题意:

在一个 \(n\times n\) 的网格上,每个位置都有一个可调整方向的箭头,货物到达该网格时会按照箭头方向移动。

现在有一个位置的箭头坏掉无法调整方向了,它的方向会被固定住。

你需要进行至多 \(25\) 次运行,每次运行你可以给每个位置指定其方向,并在你指定的位置上放上一个货物,那之后你可以知道货物从哪里离开了网格或是陷入了死循环。

你的目标是找出哪个网格上的箭头坏掉了,并确认它卡住时指向的方向。

数据范围:\(2\le n\le 100\)


  • 解法:

此题更像是一道构造题。

考虑把平面上的问题转为序列,用一个蛇形构造来排列箭头,如下:

>>>>v
v<<<<
>>>>v
v<<<<
>>>>v

我们在左上角放上货物,按照预期,货物应该会在右下角出来(奇偶的情况不同可能会是左下角出来)。

当我们发现货物出来的位置并非预期时,可以唯一确定其出来的方式(对应边界上的箭头卡成了出来的方向)。

当我们发现货物按照预期出来时,由于这时卡住的传送带恰好在其中起到了作用,我们并不好查找这个传送带。

考虑另外使用一条路径完全相反的蛇,简单分讨会发现此时倒过来的蛇中,货物一定会陷入死循环。

在陷入死循环后我们就利用一开始展开成序列的性质,在这条蛇上进行二分,如果在某个位置放下货物后货物可以到达结尾,说明卡住的传送带在它前面。

这样定位卡住的传送带后,只需再进行一次询问,把卡住的传送带的四个方向一路通到边界,就可以询问出卡住的传送带的方向了。

最后一次询问长下面这样,* 表示卡住的传送带,? 表示任意方向均可:

?^???
?^???
?^???
<*>>>
?v???

由于 \(n^2\le 10^4\),二分的次数不会超过 \(14\) 次,因此次数非常宽松。


C

交互题。

来源:CF1428H。

题目链接

  • 简要题意:

有一个圆形的旋转激光锁,锁被分成了 \(n\times m\) 个小扇形,每个扇形对应的弧上都有一个激光传感器。

锁的中心有激光发射器,如果没有遮挡,激光会直接射入激光传感器。

锁里有 \(n\) 个长度为 \(m\) 的遮光片,每个遮光片可以恰好阻挡连续的 \(m\) 个激光传感器,你不知道它们之间的位置关系。

你可以进行至多 \(15000\) 次操作,每次操作可以选定一个遮光片令其顺时针或逆时针移动一个小扇形,之后你能够得知有多少个激光传感器接收到了激光。

你随时可以停止操作,那之后你需要得到 操作结束后 所有遮光片的相对位置关系。

数据范围:\(2\le n\le 100\)\(2\le m\le 20\)


  • 解法:

注意到操作只能移动 \(1\) 个小扇形,我们可以关注移动的遮光片的头尾,因为中间大部分是没有发生变化的。

如果单独考察一个遮光片,根据对于光学的直观感受,这个遮光片能够提供的信息其实不在于自身,而在于它挡住的部分。

我们选定一个遮光片,为方便下面记为 \(P\),将 \(P\) 沿着某个方向一直旋转,设这个方向为正方向。

旋转的时候,和旋转方向相同的一端设为头部,另一端设为尾部,则遮光片始终在向“前“运动,记其座标为尾部所处的扇形的编号。

我们将小扇形从 \(0\sim n\times m-1\) 编号,顺序和 \(P\) 的旋转方向相同,即每次移动 \(P\) 我们都在增加其座标(在循环意义下)。

我们说循环意义指首尾相接,比如当 \(x=n\times m-1\) 的时候,\(x+1\) 指代 \(0\),下面与座标有关的叙述均为循环意义下的。

如果我们发现,\(P\) 移动后,被照射到的传感器数量变多了,则可以说明没有遮光片位于它移动前所在的位置。

    P-----
    ?     !
0 1 2 3 4 5 6 7 8 9
      P-----
    +     !
0 1 2 3 4 5 6 7 8 9

(把圆展开为序列想必各位都是能看懂的对吧……)

当然,从图上可以很直观感受到,如果在向前移动时,感叹号的位置也是空的,那么我们不会判定到问号处没被遮挡。

不过这其实不影响,后面我们会说到为什么没有影响。

在这里有个细节:通过抽屉原理可知,这种情况一定会发生,在 \(P\) 旋转一圈时必然会有位置被空出来。

如果继续移动发现某个时刻照射到的传感器数量不再增多,说明其刚刚所在的位置下面一定有遮光片。

        P-----
      x
0 1 2 3 4 5 6 7 8 9

注意这里一定是在某个位置先发现下方没有遮光片的前提下,再经过若干次移动才可以确定下方一定有遮光片的。

确定这里有遮光片后,我们尝试确定这个遮光片是哪个,这一步可以考虑二分。

为了更细致的描述,假设 \(P\) 在位于 \(x\) 处时触发上述条件,判断 \(x\) 处有遮光片。

通过前面的分析可得,在 \(x-1\) 处必然没有任何遮光片,否则一开始的遮光片会在 \(x-1\) 之前的位置找到遮光片。

接下来我们把 \(P\) 放到 \(x\) 处,之后在所有未确定位置的遮光片中选择一部分。

设仍未确定位置的遮光片集合为 \(S\),有可能是 \(x\) 处的遮光片的集合为 \(T\)

初始时,我们令 \(T=S\),每次二分时选择 \(T\) 中一半的遮光片,将它们向负方向移动一下。

这时接收到激光的传感器数量可能发生一些变化,记录变化后的结果为 \(res\)

之后再把 \(P\) 往负方向移动。

如果我们发现,此时接收到激光的传感器数量比 \(res\) 少,说明 \(P\) 成功遮到了 \(x-1\) 这个传感器。

      <-P-----
      ?
0 1 2 3 4 5 6 7 8 9 101112

细致分析,你会发现,此时有且仅有可能是 \(P\) 遮挡了位于 \(x-1\) 的传感器才会使得接收到激光的传感器比 \(res\) 少。

首先,由于移动是负方向的,所以唯一可能遮挡住 \(x-1\) 的只能是 \(x\) 处的遮光片。

然后,如果位于 \(x\) 的遮光片没发生移动,则 \(x-1\) 处确实会被 \(P\) 遮挡,同时新露出的 \(x+m-1\) 处会被原本位于 \(x\) 的遮光片挡住。

如下图,可以发现答案接收到激光的传感器数量确实变少了:

      <-P-----
        X-----
      -     !
0 1 2 3 4 5 6 7 8 9 101112

否则位于 \(x\) 的遮光片发生了移动,由于 \(P\) 移动之后无法再遮住 \(x-1\),所以这次移动无法遮住任何原本未被遮挡的接收器,因此答案不会比 \(res\) 更小。

这是可能的两种情况:

      <-P-----
      <-X-----
      =     +
0 1 2 3 4 5 6 7 8 9 101112
      <-P-----
      <-X-----
        Y-----
      =     =
0 1 2 3 4 5 6 7 8 9 101112

那么这样二分,如果发现成功遮挡说明移动的位置全部都不位于 \(x\),否则说明移动的位置中有至少一个位置位于 \(x\),保留存在位于 \(x\) 的遮光片一边,就一定能够二分得到一个位于 \(x\) 的遮光片。

注意由于 \(x\) 处可能存在多个遮光片,在完成二分后我们将二分出的遮光片往前拖避免影响到 \(x-1\),然后我们还需要在 \(x\) 处再判断是否有遮光片,再二分直到 \(x\) 处所有的遮光片均被找到为止。

此时我们倒回去看前面提出的关于感叹号的问题,你会发现感叹号的情况并不重要,我们只需要关注能否找到其它遮光片,而任意一个其它的遮光片都一定能够触发上述条件被找到。

即:虽然由于感叹号的存在让我们判断下面是空的条件不充分,但其足以找到所有遮光片。

到此算法流程解释完了,对于操作次数的分析比较复杂。

我们先看 \(P\),在上述流程中,\(P\) 至多旋转两圈作为移动的开销,这里大致是 \(2nm\) 的。

每次二分时,\(P\) 会被移动 \(\log n\) 级别次,总的是 \(2n\log n\) 左右。

而在二分时我们每次找出 \(T\) 中的一半,大致可以认为是这样的和式:\(\sum\limits_{i=1}^{n}\dfrac{2_n}{2_i}\),其值显然是 \(\mathcal{O}(n)\) 级别的,算总和时注意到 \(n\) 逐渐变小,所以大致是 \(\dfrac{n^2}{2}\) 的。

最后每个遮光片要往前调整位置,每个遮光片都会移动 \(\mathcal{O}(m)\) 级别次,这里差不多是 \(nm\) 次。

于是可以得到一个总询问次数的估计上界:\(2nm+2n\log n+\dfrac{n^2}{2}+nm\approx 12500\),实际可能略多一些,但符合要求。


D

通信题。

来源:JOISC 2019/2020 Day3。

题目链接

  • 简要题意:

有一张 \(N\) 个点 \(M\) 条边的无向图,点从 \(0\sim N-1\) 标号,你需要实现 A,B 两人的策略:

A 要给这张图上的每条边分配一个 \([0,A)\) 的数作为颜色。

B 会在初始时位于图上的任意一个点,他可以得知相邻的边的颜色信息。

B 无法区分 两条颜色相同的边,他只能决定一个颜色,之后从所有相邻的,有这个颜色的边中 随机 选择一条并前往这条边。

B 的目标是到达图上的 \(0\) 号节点,设他所处的位置到达 \(0\) 号节点的经过边数最少的路径经过的边数为 \(d\),他只能够在通过至多 \(d+B\) 条边的情况下完成目标。

数据范围:\(A=3,B=0\)\(A=2,B=6,m=n-1\)\(2\le n\le 20000\)\(1\le m\le 20000\)

注意在 \(A=2\) 的时候保证图是一棵树。


  • 解法:

考虑 \(A=3\) 的情况。

我们必然想用颜色来指导 B 前往正确的路线,可是路线太多就很容易走错。

我们不妨考虑,把所有正确的边用特殊的颜色标记出来,这样有个初步的想法,就是在距离 \(0\) 号节点距离为 \(d\) 的点处,用 \(d-1\) 这个颜色标示出所有可以前往距离为 \(d-1\) 的点的边。

由于其它的边的颜色并不影响决策,这可以简化一下,每条边的颜色设为连接的两点中距离 \(0\) 号节点最近的点的距离即可。

进一步,我们发现每个点周围的边只存在两种可能:\(d-1\)\(d\),所以我们即使把每条边的颜色取模 \(3\) 也仍可判断正确的路径。

判断时,只需要找到取模 \(3\) 后哪种颜色不存在,这种颜色就是目前这个点到 \(0\) 号节点的距离加一后对 \(3\) 取模后的值,反推正确路径是容易的。

接下来考虑 \(A=2\) 的情况。

沿用上述思路,发现在 \(A=2\) 的时候我们无法判断哪个方向是对的,因为我们找不到不存在的颜色了。

不过有趣的事情在于我们此时的图是一棵树,这意味着任何两个到 \(0\) 的距离相同的点之间没有直接的连边。

我们像前面一样分配颜色,则每条边是 0/1 交替的,当一个点连接的边数为 \(1\) 自不用说,若连接的边数大于 \(2\),情况只可能是这个点有超过一个儿子,选择只有一条边的那个颜色就是正确的。

上述两种情况可以直接确定父亲的方向,于是一路走上去即可。

剩下就要考虑树上的链的情况了,我们不妨假设目前 B 位于一条无限长的链上,他需要确定 \(0\) 号节点位于哪个方向。

注意到 \(B=6\),我们至多可以走 \(3\) 次,那之后我们必须找到正确的方向。

分析我们获得的信息,\(3\) 次移动一共可以到达 \(4\) 个点,看到 \(5\) 条边的颜色信息。

如果我们将构造稍作转换,在链上通过一些方式使得考察 \(5\) 条相邻的边后能够确定方向,即可完成本题。

一种可能的构造是 \(110010\),我们从链顶向下无限循环这个串,取其中长度为 \(5\) 的子区间正反阅读,会发现正着的和反着的没有重合,我们就可以判断我们考察的 \(5\) 条边的方向了。

实现的时候细节较多。


E

通信题。

来源:IOI 2024 Day1。

题目链接

  • 简要题意:

A 要把一个长度小于等于 \(1024\) 的二进制串 \(S\) 传递给 B,他可以发送至多 \(66\) 个包含 \(31\) bit 的数据包。

C 会在传递过程中搞破坏,每个发送过去的数据包,C 都会选择特定的 \(15\) 个 bit,将它们篡改。

C 的行为是不确定的,即篡改后的信息可能是任意的,但 C 每次篡改的位置一定是相同的。

A 知道哪些位置会被 C 篡改,而 B 不知道。

B 会按顺序接收到 A 发送的所有数据包,当然是经过篡改的。

A 可以知道 B 接收到的数据包是怎样的(但其实没用)。

请你实现 A,B 的策略,让 B 能够复原 A 发送的 \(S\)

数据范围已经全部写在题意中。


  • 解法:

这题的解法实在是高,看完就懂但就是想不到啊。

首先,对于 \(S\) 做一步转换,在最前面加上一个 1 并补 0 直到长度为 \(1025\),这样可以将不定长的字符串转为定长的。

考虑发送 \(1025\) bit 后还能传输什么信息,一共有 \(66\) 个数据包,每个数据包最多只能传递 \(16\) 位有效信息,总共就是 \(66\times 16=1056\)

注意到 \(1056-1025=31\),恰好为数据包的长度,这暗示我们尝试寻找一种方式,花费 \(31\) bit 传输所有不被篡改位置的信息。

一个非常关键的事情是 B 接收到的信息是有顺序的,顺序本身也是一种信息。

我们设第 \(i\) 个位置是不被篡改的,往 \(i\) 后面循环数 \(d_i-1\) 个位置都是会被篡改的,而 \(d_i\) 个位置恰好是不被篡改的。

传输的过程中,我们先在 \(i\) 这个位置传输 \(d_i-1\)0,然后再传输一个 1,类似前面对 \(S\) 的操作,B 接收信息后可以解码出 \(d_i\)

这种传输方式可以让所有不被篡改的位置互相连接,形成一个环,而被篡改的位置无论如何也无法形成一个长度为 \(16\) 的环。

简单解释:由于篡改的位置只有 \(15\) 个,必然不可能自主形成长度大于 \(15\) 的环,而由于其它位置已经用于形成长度为 \(16\) 的环了,贴到其它位置也不会有入度成环。

于是找到这个环就可以得到所有不被篡改的位置,由于 \(d_i\) 的总和一定是 \(31\),为了传递 \(d_i\) 我们只花费了 \(31\) bit,符合要求。

posted @ 2025-02-21 16:28  小山云盘  阅读(62)  评论(4)    收藏  举报