2020.02.25【NOIP提高组】模拟B组比赛总结反思

这次比赛得了152分,第24名,不理想,可能是题目不合胃口吧。

T1 抓猫

比赛时

一开始想到用bfs来找环,但是想到一个样例SWWW,发现如果用bfs的话就错了,然后仔细想想,就发现能用并查集来做。但是,二维的并查集该怎么弄呢(我太弱了)?于是我就想了一种方法,如下如就是给每个格子编号,如下图。在这里插入图片描述
那这样子如何才能在O(1)的复杂度内完成编号呢,其实啊,仔细观察一下图,我们就可以发现一个格子的编号就是 ( i 1 ) m + j (i-1)m+j ,不错吧。然后我们就可以愉快地用并查集了。做法就是对于每一个格子,找到里面的猫在这个格子下一步走到的格子,然后用把这两个格子合并(用并查集),最后O(n)循环找到有多少个最古老的祖先。PS:如果想要更快些,可以采用路径压缩。

比赛后

同比赛时

T2 街道

比赛时

比赛时看到这道题就没有思路,我想,诶算了,弃疗。

比赛后

比赛后听了正解,发现又是一道并查集,只不过还要加上hash而已。那应该怎么做呢?
其实很简单,首先设定一个值,就是hash中mod的值,因为这题时间比较紧,所以说对于这个mod,我们就需要定一个素数,我定了 245507 245507 (好像 233437 233437 也行)。读入关系时,可以先把每一个字符串的hash值求出来,然后对于平行的情况,我们就把 x , y x,y 还有 x + m o d , y + m o d x+mod,y+mod 合并起来;如果是垂直的话,我们就把 x , y + m o d x,y+mod 还有 x + m o d , y x+mod,y 合并起来。对于 W a t e r l o o Waterloo 的情况其实就是两条街道同时垂直和平行。
之后对于题目所给的两条街,如果符合 f i n d ( x ) = = f i n d ( y ) f i n d ( x + m o d ) = = f i n d ( y + m o d ) find(x)==find(y)||find(x+mod)==find(y+mod) ( f i n d ) (find为并查集的函数) 的话就输出 p a r a l l e l “parallel” 同样的如果符合垂直的条件,就输出 i n t e r s e c t “intersect” 其余的全部都是 u n k n o w “unknow” 。这道题就这么完了。

T3 秤

比赛时

比赛的时候打暴力打炸了,无奈交上去,但拿了20分。

比赛后

没想到,听了正解后,发现这道题就是暴力。对于这道题,每次他给你读入两个数,你可以把大的放在前面(为后面做铺垫)。接着,你就可以进行暴力dfs,有以下三种情况:

  1. 左右两边都是物品,就直接两两判断;
  2. 如果两边有一个是秤,另一个是物品,那么dfs秤那边,如果秤那边也是合法的再判断物品;
  3. 两边都是秤,就分别dfs再回溯回来就好了。
    这题就没了。

T4 糖果

比赛时

比赛时我想到了带权中位数,然后就这么做了。随后发现不行,但也只能这样做了WA32。

比赛后

比赛后我想到了一种贪心的想法,试了一下,但只能拿76分。
听了正解后,明白了这题是个dp,只不过dp数组是bool数组。
我们可以设 f i , j f_{i,j} 表示到第 i i 个数,最小的差为 j j 可不可行。
只要满足 f i 1 , j = = t r u e f_{i-1,j}==true 那么状态转移方程就是:
f i , j + k b i ( a i k ) b i = t r u e f_{i,|j+k*b_i-(a_i-k)*b_i|}=true
最终的答案就是 f n , j = = t r u e f_{n,j}==true 中最小的 j j ( 0 j 200 ) (0≤j≤200)

总结

这次比赛有点“不合胃口”,没事继续努力!加油!
别忘了我的blog

猜你喜欢

转载自blog.csdn.net/LeeCongWei/article/details/104534811