Google Kickstart 2019 刷题笔记

Practice Round 2019

1. Number Guessing

  • 水题,略过

2. Mural

  • 基于如下事实:只要你想,你可以保住任何一段长为 N / 2 \lceil N/2 \rceil 的墙,故只要求和最大的一段墙即可

3. Kickstart Alarm

  • 本题的精髓是如何快速求 a 1 + a 2 + . . . + a n a^1+a^2+...+a^n ;类似于快速求幂法,只是要同时维护两个变量 a 1 + a 2 + . . . + a i a^1+a^2+...+a^i a i a^i

Round A 2019

1. Training

  • 排序之后用窗口扫描即可;结果我用Go写第二问就超时,用C写就过了,可能是Go的IO效率低?

2. Parcels

  • 本题涉及计算几何的经典问题:给定 N N 个点,如何用 O ( N ) O(N) 时间求出其中最大的曼哈顿距离?(或给定 N N 个点,预处理后,如何用 O ( 1 ) O(1) 时间求出新的一个点到其中最大的曼哈顿距离?)
  • 上面的问题解决后,就可以用二分猜测法,每次用 O ( R C ) O(RC) 时间扫描全盘来验证,总用时 O ( R C l o g ( R + C ) ) O(RC\cdot log(R+C))
  • 注意到若一个点可以实现最小距离 k k ,那么与它相邻的点可以实现的最小距离一定为 k 1 k-1 k k k + 1 k+1 之一;故我们甚至没有必要进行二分猜测,只要全盘扫描一遍,记录找到的最小距离即可,总用时 O ( R C ) O(RC)

3. Contention

  • 基于如下事实:由于每次新覆盖的区域与之前的覆盖顺序无关,故为使每次新覆盖区域的最小值最大,必须使最后一次的区间新覆盖的区域尽可能大
  • 这里倒着解答,每次取出新覆盖区域最大的区间,本人只看懂了每次用 O ( N ) O(N) 扫一遍的方法,总用时 O ( N 2 ) O(N^2)

Round B 2019

1. Building Palindromes

  • 区间求和,判断数量为奇数的字母个数是否不超过1即可;由于不需要求每个字母的具体数量,所以可以用位运算异或来减少运算量
  • 一看到区间求和我就上了树状数组,后来意识到这些字母并不会更新,所以可以用前缀和达到 O ( N ) O(N) 的复杂度

2. Energy Stones

  • 基于如下事实:若两块石头 i i j j 会被吃,且 S i L j < S j L i S_iL_j<S_jL_i ,则 i i 一定先于 j j 被吃;根据该事实进行排序,然后确定每块石头是否被吃即可
  • 用动态规划,比较特别的是这是一个“我为人人”的动规,即用 m a x _ e n e r g y ( i , t ) max\_energy(i, t) 更新 m a x _ e n e r g y ( i + 1 , t ) max\_energy(i+1, t) m a x _ e n e r g y ( i + 1 , t + t i m e [ i ] ) max\_energy(i+1, t+time[i]) 的最大值

3. Diverse Subarray

  • 本题的精髓是使用差分的区间和来计算该区间上可以带的礼物的最大值,于是遍历所有左端点,求出右边区间的最大前缀和即可
  • 这里用树状数组来做到单点更新和区间求最大前缀和,另外需要一个哈希链表来记录下一个被更新的点在哪里

Round C 2019

1. Wiggle Walk

  • 一开始我也想到用某种办法一次性跨过之前走过的方块,奈何一下子想不出合适的数据结构,不得已看了解析,原来就是用STL的map存储区间

2. Circuit Board

  • 如果熟练的话,本题应该能看出来这是直方图最大矩形的衍生问题;看出来之后从左到右用竖线做底扫一遍即可
  • 做第2问的时候没注意multiseterase的语义,移除元素 x x 之一应该写ms.erase(ms.find(x)),否则就是移除全部 x x

3. Catch Some

  • 先假设最后一次也要回家,设 m i n _ s t e p ( i , j ) min\_step(i, j) 为使用前i种颜色访问j只狗所需的最小步数,则 m i n _ s t e p ( i , j ) = m i n ( m i n _ s t e p ( i 1 , j k ) + s u m ( i , k ) ) min\_step(i, j)=min(min\_step(i-1, j-k)+sum(i, k)) ,其中 s u m ( i , k ) sum(i,k) 是第i种颜色第k只狗的距离
  • 为了使最后一次区别对待,需要用两个数组 m i n _ s t e p _ a l l _ h o m e d ( i , j ) min\_step\_all\_homed(i, j) m i n _ s t e p _ o n c e _ u n h o m e d ( i , j ) min\_step\_once\_unhomed(i, j) ,这样最小答案就在后者里

Round D 2019

1. X or What?

  • 基于如下事实:合法区间必为 xor-even 数的个数为偶数的区间,而最大区间至少有一边在数组的端点,这样每次只需回答一个判断题,即取左端点还是右端点

2. Latest Guests

  • 这题要是改成所有人都朝一个方向转就简单了,而考虑两个方向时只需要一个小技巧,就是在记录每户最后到访者时顺便记下时间,然后比较两个方向哪个更新即可

3. Food Stalls

  • 这题和简单选点问题不同的是加上了距离代价,和上题有点相似的是,如果假设仓库必须建在所有商店的右边,那么就可以用绝对距离计算代价,然后用大小为 K K 的最大值堆从左到右扫一遍,留下的 K K 个点即是 K K 个商店
  • 由直线上多点距离之和的性质得,仓库必须建在 K + 1 K+1 个点的中点上,故先在左边建 K / 2 \lfloor K/2 \rfloor 个商店,再在右边建 K / 2 \lceil K/2 \rceil 个商店,最后求加在一起的最小值即可
  • 有个坑就是 x x c c 都特别大,要开long long才能解决,下次要注意看题

Round E 2019

1. Cherries Mesh

  • 简单图问题,设用黑线连在一起的为一组,则答案为 N + G 2 N+G-2 ,其中 N N 为总点数, G G 为总组数

2. Code-Eat Switcher

  • c o d e / e a t code/eat 排序,大的放前面,每次优先将前面的 c o d e code 时间占满,然后在满足总 c o d e code 时间的情况下剩余的 e a t eat 时间一定最大
  • 这题在边界判断上卡了很久,最后自己造数据才发现问题,还有又踩了一次long long的坑

3. Street Checkers

  • 先考虑每个单独的 X X ,设 X X 可以分解质因数为 X = 2 n a 1 m 1 a 2 m 2 . . . X=2^n\cdot a_1^{m_1}\cdot a_2^{m_2}\cdot ... ,则 X X 符合条件等价于:
    • n = 0 n=0 X X 是质数(或 1 1
    • n = 1 n=1
    • n = 2 n=2 X / 4 X/4 是质数(或 1 1
    • X = 8 X=8
  • 然后就是怎么判断质数的问题了,由于 X 1 0 9 X\le 10^9 ,故可以用 X X 除以 2 2 1 0 9 \sqrt{10^9} 之间的质数来判断,这之间有 3401 3401 个质数,虽然我觉得复杂度挺高但还是过了

Round F 2019

1. Flattening

  • 这题属于容易做也容易错的题,方法很简单,就是用动态规划,从左到右扫一遍,并且动态更新 m i n _ r e b u i l d ( l a s t _ h e i g h t , c h a n g e s ) min\_rebuild(last\_height, changes) 数组,复杂度 O ( N 3 ) O(N^3) 还是绰绰有余的
  • 我一开始错就错在试图节约 l a s t _ h e i g h t last\_height 的初始数量,因为后面的高度可能会影响前面的高度,所以必须一开始就把所有高度加入状态集中

2. Teach Me

  • 我一开始想的是计算 i i 不能教的人,但这样显然不能简化为子集查询的问题;应该是计算不能教 i i 的人,这样只要查询与 i i 的某个子集相同的人数
  • 之所以能用子集查询是因为每个人最多有 5 5 个技能,且总技能数不超过 1000 1000 ,所以可以用long long作为任意子集的key

3. Spectating Villages

  • 我想的和答案一样,都是看成树然后动态规划,但我觉得我的简单些(答案的动态规划套了娃)
  • 维护三个最大值 l i g h t e d _ b y _ i t s e l f lighted\_by\_itself l i g h t e d _ b y _ c h i l d r e n lighted\_by\_children u n l i g h t e d unlighted ,第二个值需要注意,因为如果在所有子节点都灭灯的时候取到最大值,必须强行让一个子节点亮灯
发布了3 篇原创文章 · 获赞 0 · 访问量 225

猜你喜欢

转载自blog.csdn.net/Cocity/article/details/104703190