A.给一个字符串,要求找最后一个字符a的位置,直接模拟就好
B.给一个N个点和M条边的图,要升序输出每个点所有直接相连点,直接用vector数组保存,再排序输出就好
C.给一个排列(排列是把1 ... N这N个数按一定顺序排列),求上一个排列 使用std::prev_permutation 如果是求下一个排列 std::next_permutation
D.给一个长度N的数组,每次操作如下:1 <= i <= N 如果ai是2的倍数(ai % 2 == 0),然后ai <- ai / 2; 1 <= i <= N 如果ai是3的倍数(ai % 3 == 0),然后ai <- ai / 3; 求最后a1 = a2 = a3... = an的最少操作.
先对数组里面的所有数字ai求最大公约数gcd,显然最后的数组应该是a1 = a2 = a3 =...= an = 这个gcd,然后直接模拟,对于每个数ai,先把这个gcd除了,如果是2的倍数,ai / 2; 如果是3的倍数,ai / 3, 如果最后ai > 1说明有其他的质因子,输出-1;
E.给一个H行W列的二维格子,每个格子有S, . 或 # 三种中的一种,其中S是出发点,#是障碍物,.是可以通过的,要判断是否存在一条从S出发,再回到S的路径,且路径长度>=4.
首先,考虑一下S点相邻的四个顶点,如果其中某两个顶点相连,存在一个(x1, y1) .... (xn, yn)的路径(这条路径 >= 3),再加上S这个点就可以找到一条从S出发,再回到S,且路径长度>=4的路径,然后问题转化为求与S点相邻的四个顶点是否相连,用并查集就好了。
F.有N张卡,每张卡上面有一个数字ai。如果有一个背包包含数组的前K张卡(1 < K < N),然后每次从背包里面抽一张卡,记下这张卡的数字,再把卡,放回去,连抽两次,求max(x, y)的期望。
显然,连抽两次,总的可能数目是 K* K;剩下的考虑这样一种形式,如果背包里面这K张卡是有序的,那我们就可以枚举其中一张卡来计算这个概率(卡的左边的必然比它小,只要计算左边比他小的个数就好),但是这个数列的前K项是无序的,所以我们用树状数组来进行这个统计。
G.求一个长度为N的递增的最大值小于等于M,且相邻两个数 % 3不能相等的数组个数
考虑 b1=a1,bi=ai−ai−1,bn+1=m−an, 则b1 + b2 + ... + bn = m , b 和 a 一一对应,所以 b 的数量等于 a 的数量,问题转化为算 b 的数量。
依据题意, b1 和 bn+1 可以随意,其余 bi 需要满足模 3 余 1 或者模 3 余 2(且相邻两个数 % 3不能相等,所以bi 模 3 不可能与 0)。
将 bi 分解成 bi=3yi+xi,其中 xi=bi%3,yi=⌊bi/3⌋。
若固定 xi ,则 yi 与 bi 一一对应。枚举所有可能的 x,计算每种情况下 y 的数量,就能算出 bb 的数量。
对于xi的部分,枚举 l=x1 ,枚举 r=xn+1 ,枚举剩余 xi 中 xi=2 的数量 i ,则剩余 t=m−l−r−(n−1)−i 还没有使用(其中m是总数,(n - 1) + i是里面xi = 1 和 xi = 2的总数),这样的 x 有 C(n−1, i)种。而剩余部分就是 ,所以若 t 不是 3 的倍数则无效,否则
,由插板法有满足这样条件的 y 有 C(n+t, 3n)中。
Ex.先鸽着,后面回来补