Google Kick Start 2019 G轮题解

首发于彼得攀的小站

查阅更多的题解,请点击
github传送门 (求个star哇)

A. Book Reading

题目地址

Solution

解法

本题如果采用暴力求解,最坏情况下,每个读者都需要 O ( n ) O(n) O(n) time, 则总的时间复杂度为 O ( n q ) O(nq) O(nq) time. (一个简单的例子,q个读者对应的 R i R_i Ri都是1,那么每个读者都要算n次)

为了避免上述暴力过程中出现的重复计算,可以将结果提前存下来, c o u n t ( i ) count(i) count(i)代表i的倍数且未被撕掉页的个数。那么计算整个count数组需要 N + N / 2 + N / 2 + ⋯ + 1 = N ( 1 + 1 / 2 + 1 / 3 + ⋯ + 1 / N ) N+N/2+N/2+\cdots+1=N(1+1/2+1/3+\cdots+1/N) N+N/2+N/2++1=N(1+1/2+1/3++1/N):

其中的 N ( 1 + 1 / 2 + 1 / 3 + ⋯ + 1 / N ) N(1+1/2+1/3+\cdots+1/N) N(1+1/2+1/3++1/N)是调和数, H n = 1 + 1 2 + 1 3 + ⋯ + 1 n = ∑ k = 1 n 1 k H_{n}=1+\frac{1}{2}+\frac{1}{3}+\cdots+\frac{1}{n}=\sum_{k=1}^{n} \frac{1}{k} Hn=1+21+31++n1=k=1nk1,利用极限可以得到 lim ⁡ n → ∞ ( ∑ k = 1 n 1 k − ln ⁡ n ) = γ \lim _{n \rightarrow \infty}\left(\sum_{k=1}^{n} \frac{1}{k}-\ln n\right)=\gamma limn(k=1nk1lnn)=γ,最终有 H n ∼ ln ⁡ n + γ H_{n} \sim \ln n+\gamma Hnlnn+γ

所以整个算法的时间复杂度为 O ( n l o g n + q ) O(nlogn+q) O(nlogn+q) time.

复杂度分析

见上, O ( n l o g n + q ) O(nlogn+q) O(nlogn+q) time

代码

code

B. The Equation

題目地址

Solution

解法

这道题思路很清晰:将 A i A_i Ai转化为二进制表示, ( A 1   x o r   k ) + ( A 2   x o r   k ) + ⋯ + ( A k   x o r   k ) (A_1\ xor\ k)+(A_2\ xor\ k)+\cdots+(A_k\ xor\ k) (A1 xor k)+(A2 xor k)++(Ak xor k)仅由二进制表示中,每位上1的个数和k对应位置取值(0或1)决定,令 c o u n t ( i ) count(i) count(i)为二进制表示中第 i i i位(由低到高标号,从0开始)1的个数, c o u n t ( i ) ∈ [ 0 , n ] count(i)\in [0,n] count(i)[0,n]

注意 0 ≤ M ≤ 1 0 15 且 0 ≤ A i ≤ 1 0 15 , 0\leq M\leq10^{15}且0 \leq \mathrm{A}_{\mathrm{i}} \leq 10^{15}, 0M10150Ai1015, for all i。由于 2 49 < 10 … … 15 < 2 50 2^{49}<10……{15}<2^{50} 249<1015<250,而 2 50 2^{50} 250的二进制表示有51位(注意不是50位,博主就是写成了50位,导致大数据集没有过),所以 i ∈ [ 0 , 50 ] i\in[0,50] i[0,50]

要求最大的k,可以用贪心策略,从高位到低位依次枚举,在满足 ( A 1   x o r   k ) + ( A 2   x o r   k ) + ⋯ + ( A k   x o r   k ) ≤ M (A_1\ xor\ k)+(A_2\ xor\ k)+\cdots+(A_k\ xor\ k)\leq M (A1 xor k)+(A2 xor k)++(Ak xor k)M的情况下,k当前位取1。

可以提前判断是否存在符合题意的k:即最小化 ( A 1   x o r   k ) + ( A 2   x o r   k ) + ⋯ + ( A k   x o r   k ) = ∑ i ≤ 50 ( 1 l l < <   i ) ∗ m i n ( n − c o u n t ( i ) , c o u n t ( i ) ) = s u m (A_1\ xor\ k)+(A_2\ xor\ k)+\cdots+(A_k\ xor\ k)=\sum_{i\leq 50}{(1ll<<\ i)* min(n-count(i),count(i))}=sum (A1 xor k)+(A2 xor k)++(Ak xor k)=i50(1ll<< i)min(ncount(i),count(i))=sum,若 s u m > m sum>m sum>m,则不存在符合题意的k。

复杂度分析

由于 A i A_i Ai二进制表示的位数上界为常数,所以可以认为上述过程是 O ( N ) O(N) O(N) time.

代码

code

C. Shifts

题目地址

Solution

解法

设两个保安分别为A和B,总共有n个时间段,每个时间段有3种选择,共有 O ( 3 n ) O(3^n) O(3n)种不同的方案,直接暴力搜索是 O ( 3 n ) O(3^n) O(3n) time,只能过小数据集。直观的想法是对搜索过程进行剪枝(参考该方案),暴力求解的dfs搜索树共有n层,下一层的节点数是上一层节点数的3倍,总共有2种有效的剪枝策略:

  • 当搜索到第i层时,当前节点:A和B的开心值均已满足要求,则无需继续搜索,之后的排班方案对结果无影响,res+=pow(3,n-i)
  • 当搜索到第i层时,当前节点:之后的每个时间段,A和B均参与工作,开心值总和不满足要求,则无需继续搜索,这里需要提前计算后缀和

官方题解:官方题解是利用meet in the middle来减少搜索空间,整个思路的本质同上,且更优,然而merge的时候需要range tree,本人并不会。。

复杂度分析

O ( 3 n ) O(3^n) O(3n) time.

代码

code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值