2024 ICPC 上海站(BCDGI)

第一场区域赛,惨遭打铁。赛时只出了BCI。赛后补了DG,发现两道题都没有那么难,只能说还得加训。。。

C,I相对简单一些,就不写题解了。

code_C

B

补得最难绷的一题。先写了一个栈维护dfs路径的写法,TLE15;又写了一个set维护结点之间访问关系的写法,TLE26

我的做法就是维护当前正在搜索的路径,对于下一步搜索的方式,有几种可能性:(设当前走到了点u,下一个目标点为v

  1. u,v之间有边 -> 直接走u,v
  2. u,v之间无边,但u可以直达一个未访问过的结点(即不在当前路径上的点)->一定非法,必须要加一条新边(u,v)
  3. u之后的结点均已被搜索过 -> 回溯并重复1,2过程。若发现最后回溯到的所有点均无法继续走,则说明这个联通块内的点均已被搜索过。则由题可知直接对目标点所在的另一个联通块dfs即可,不需要加新边。

我的所有写法都离不开一个致命问题 —— 即需要线性(或者说暴力)维护当前搜索的路径(要想优化维护可能需要一些ds,但不知道咋写),导致可能有些数据会一直让我卡在暴力回溯的部分而TLE

最后还是屈服于了递归,写了一个递归来简化维护回溯路径的写法,直接就过了。

ACcode

TLE on 26 code

D

逆天构造题,借用其他博客上的方法补出来了。

可以发现,只要能变换到结尾两个数字都是0的情况,就一定可以将所有数字都变为0:只需要倒序把剩下的1都变为0即可。

所以问题转化为找到一种操作方式,使得结尾两个数字都为0

n==3的时候特判一下,剩下的情况均为n>=4

只考虑最后的4个数字,除了最后两个均为0的情况一定可行,还剩下12种情况,其中5种情况可行,7种情况不可行。具体见代码。

可行的情况一定为Yes,但不可行的情况不一定为No。因为在这4个字符前面的字符也可以对这4个字符产生影响。具体如何影响,需要看从左到右可以过来多少个1。而对于不可行的7种情况,是否可以变为可行,也取决于前面可以过来1的数量。具体可以自己模拟一下。

而如何计算结尾4个数字之前的串能过来多少个1,这个类似于括号匹配:把1当成左括号,0当成右括号。每一个0可以抵消掉其左侧的一个1。从str[0n5]遍历一下,就可以得出最多可以有多少个连续的1结尾,即上述“前面可以过来1的数量”。

code

G

中位数二分 + 贪心

显然可以二分答案,设正在二分的答案为mid,则可以根据mid来得到每一条直线能匹配的最大or最小的x

具体地,对于a>0的直线,任意x>=(midb)/a均满足y>=mid;而对于a<0的直线,任意x<=(midb)/a均满足y>=mida==0时,与x无关,只有b>=mid时满足y>=mid。将所有a>0的直线对应的x放入pos数组中,将所有a<0的直线对应的x放入neg数组中;

故将直线按照斜率分成3组:>0,<0=0。则剩下的问题就是将c数组表示的竖线与求得的x一一匹配,使得y>=mid的交点数量尽可能多。

显然有一个贪心的想法:a<0的直线尽可能匹配较小的xa>0的直线尽可能匹配较大的x(证明略)。因此将c数组排序后,将pos数组与c的后缀作最大匹配,neg数组与c的前缀作最大匹配,再加上a==0的情况,即为最大的y>=mid的交点数量。与(n+1)/2作比较并调整二分边界即可。

作最大匹配的过程:尽可能把容易匹配的点先作匹配,而不是直接按照顺序作一一匹配(易错!)-> 双指针匹配即可。

代码方面要注意两个问题:

  1. 对于二分的mid,每条直线得到的x要根据值的正负和直线斜率的正负做到正确取整。具体见代码。
  2. 二分边界要取大一些,这个暂时还没懂为什么。

code

posted @   jxs123  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示
主题色彩