3.9美团第一次
4.小美的朋友关系
小美认为,在人际交往中,但是随着时间的流逝,朋友的关系也是会慢慢变淡的,最终朋友关系就淡忘了。
现在初始有一些朋友关系,存在一些事件会导致两个人淡忘了他们的朋友关系。小美想知道某一时刻中,某两人是否可以通过朋友介绍互相认识?
事件共有 2 种:
1 u v:代表编号 u 的人和编号 v 的人淡忘了他们的朋友关系。
2 u v:代表小美查询编号 u 的人和编号 v 的人是否能通过朋友介绍互相认识。
注:介绍可以有多层,比如 2 号把 1 号介绍给 3 号,然后 3 号再把 1 号介绍给 4 号,这样 1 号和 4 号就认识了。
输入描述:
第一行两个整数 n,m,表示人数和事件数。
接下来 m 行,每行有三个整数 t,u,v,表示事件类型和两个人的编号。
接下来一行一个整数 q,表示小美的查询次数。
接下来 q 行,每行有两个整数 u,v,表示小美的查询。
保证没有重复的事件。
输出描述:
对于每个查询,如果 u 和 v 可以通过朋友介绍互相认识,输出 “Yes”,否则输出 “No”。
示例:
输入例子:
5 3 5
1 2
2 3
4 5
1 1 5
2 1 3
2 1 4
1 1 2
2 1 3
输出例子:
Yes
No
No
例子说明:
第一次事件,1 号和 5 号本来就不是朋友,所以无事发生。
第二次事件是询问,1 号和 3 号可以通过 2 号的介绍认识。
第三次事件是询问,显然 1 号和 4 号无法互相认识。
第四次事件,1 号和 2 号淡忘了。
第五次事件,此时 1 号无法再经过 2 号和 3 号互相认识了。
思路:
并查集,但是对于查询反着来,相当于时光倒流,站在后面看之前。
- 根据初始条件,构建朋友关系边
- 根据查询条件1,构建淡忘的关系边
- 然后将初始条件中的并且不在淡忘条件中的边,构建并查集
- 现在构建的,是最后所有关系淡忘完的朋友圈
- 此时,对于所有查询逆序。
- 如果查询的两个人在同一个朋友圈(所有关系都断开了还能相通),输出Yes,否则输出No
- 如果遇到了淡忘条件,将淡忘条件加入并查集,恢复关系
1 | n, m, q = map(int, input().split()) |
5.小美的区间删除
小美拿到了一个大小为的数组,她希望删除一个区间后,使得剩余所有元素的乘积末尾至少有个。小美想知道,一共有多少种不同的删除方案?
输入描述:
第一行两个整数,表示数组大小和末尾的个数。
第二行个整数,表示数组中的元素。
输出描述:
一个整数,表示答案。
示例:
输入例子:
5 2
2 5 3 4 20
输出例子:
4
例子说明:
第一个方案,删除[3]。
第二个方案,删除[4]。
第三个方案,删除[3,4]。
第四个方案,删除[2]。
思路:
乘积末尾有k个0意味着乘积可以被 整除,又 。因此,问题转化为找到删除区间后,剩余所有元素的乘积中2和5的因子数量都至少有k个。
- 预处理每个元素的2和5的因子数量,记录前缀和,分别存储在cnt2和cnt5数组中。
- 用双指针l和r维护一个区间,使得去除区间内的元素因子数量之外,剩下的至少有k个,那么这个区间就是可以被删除的区间。
- 每一次,固定l,r向右移动,此时计算剩余的2和5的因子数量,并判断是否小于k,如果小于k,表示剩余的元素不满足条件,那么l向右移动,重新找一个起点区间。如果大于k,表示剩余的元素满足条件,那么r向右移动,查看下一个区间,是否满足条件。
- 每次移动,都用ans记录所有的区间数(如果大区间删掉没问题,那么小区间也没问题),最后输出ans。
1 |
|
3.16美团第二次
树状数组补充
4.小美的众数
小明要求出一个数组的所有子数组的众数之和,定义子数组的众数为出现次数最多的那个数。如果有多个数出现次数最多,那么众数是其中最小的那个数。
输入描述
第一行输入一个正整数n,代表数组的大小。
第二行输入n个正整数,代表数组的元素。输出描述
一个正整数,代表所有区间的众数之和。
示例:
输入
3
2 1 2
输出
9
说明
[2],[2,1,2],[2]的众数是 2。
[2,1],[1],[1,2]的众数是 1。
因此答案是 9。
思路:
我整个子数组的数量为,因此我们只需要统计众数2的个数,即可知道众数1的个数,反之亦然
对于这题,我们可以将1视为-1,2视为1,那么区间 [l, r]
的和就相当于区间中2的数量减去1的数量,如果该区间的和>0,则说明对于区间 [l, r]
而言,区间的众数为2,否则为1。
为了区间和的计算方便,这里采用前缀和来进行处理:
-记s[i]为前i个数的和,那么区间 [l, r]
的和可以表示为: s[r]-s[l-1]
将本题转换为,对于每个位置r,找到其左侧所有满足 s[r]-s[l]>0.
的数量其中查询左侧满足的数量个数可以用树状数组来维护查询。
值得注意的是:由于这里将所有的1都变成-1了,那么所有的前缀和的范围为[一n, n],因此在使数状数组的时候要加上偏移量n+1
1 |
5.小美的逆序对
小明拿到了一个排列,他定义 f(i)
为:将第 i
个元素取反后,形成的数组的逆序对数量。小明希望你求出 f(1)
到 f(n)
的值。(排列是指一个长度为n的数组,1到 n每个元素恰好出现了一次)
输入描述
第一行输入一个正整数n,代表排列的大小。
第二行输入n个正整数,代表排列的元素。
输出描述
输出n整数,第i整数是
f(i)
的值。
示例:
输入
3
1 2 3
输出
0 1 2
说明
第一个元素取反,数组将变成[-1,2,3],逆序对数量为 0。
第二个元素取反,数组将变成[1,-2,3],逆序对数量为 1。
第三个元素取反,数组将变成[1,2,-3],逆序对数量为 2。
思路:
- 首先要求出来原来数组的逆序对数量(记为ans),常见的方法是树状数组或者归并排序, 统计逆序对有两种遍历方法,一种是看前面的元素有几个比当前元素大(记为
pre[i]
),或者是看后面的元素有几个比当前元素小(记为suf[i]
)。 - 在遍历每个元素求
f(i)
的时候,要分别求出当前元素取反之后,对前面元素和后面元素的影响,f(i) = ans + 对前面的影响 + 对后面的影响
- 对后面元素:取负之后,后面的元素一定比当前元素大,相比原来少了suf[i]个逆序对,所以ans要减去suf[i];
- 对前面元素:取负之后,前面的元素一定比当前元素小,所以现在一定形成了i-1个逆序对,再减去pre[i],就求出变化量了。
- 所以 f ( i ) f(i)f(i) = ans + ((i - 1) - pre[i]) + (-suf[i])
- 求pre[i]和suf[i]的过程要用到树状数组
3.24拼多多第一次
×3.超级快递点
多多快递站共有n个快递点,n个快递点之间通过m条单向车道连接。快递员从任何一个快递站点出发,都无法通过单向车道回到该站点。也就是说,n个快递点组成一张有向无环图。对于快递点u,如果对于所有的快递点 v(v!=u), 快递员都可以从u走到v,或者从v走到u,那么则评定站点u为超级快递点。请你帮忙算一算,一共有多少个超级快递点。
输入描述:
第一行 2个数字n(2<=n<=310^5) , m(1<=m<=310^5) , n为快递点个数,m为单向车道个数。
接下来的m行每行两个数字 u,v(1<=u,v<=n, v!=u),表示有一条站点u指向v的单向车道。
输出描述:
请输出个数字,表示超级快递点的个数。
示例:
输入示例
7 7
1 2
2 3
3 4
4 7
2 5
5 4
6 4
输出示例
2
说明
快递点 4 可以到达 4,7,可以从1,2,3,5,6 到达, 评为超级快递点 快递点 7 可以到达 7,可以从 1,2,3,4,5,6到达,评为超级快递点
思路:
有点像图中的求关键节点
4.多多的回文修建
多多有一个长度为 n 的字符串, 这个字符串由26个小写字母组成.
多多可以对这个字符串进行多次操作, 每次操作可以把该字符串中一段连续的回文子串删除(单个字符也属于回文串), 删除后剩下的串会拼在一起.
请问最少需要多少次操作可以将这个字符串删光.
输入描述:
第一行, 包含一个正整数 T(1<=T<=20) 代表测试数据的组数.
对于每组测试数据, 仅有一行, 代表这个字符串.
(1<=n<=500)
保证 Σn 不超过 3000
输出描述:
对于每组数据输出一行整数, 代表多多在进行最少多少次操作后, 可以将这个字符串删光.
示例:
输入示例
3
mwapd
tvuvv
yxxmi
输出示例
5
3
4
说明
对于 tvuvv
第一步: 删除u, 此时剩下tvvv
第二步: 删除vvv, 此时剩下t
第三步: 删除t
思路:
f[i][j]
表示将区间 [i,j]
删除的最小次数. 转移时枚举k将区间分为[i,k]和[k+1,j]两部分, 如果 a[i]==a[j]
则可以选择从 f[i+1][j-1]
转移,因为可以选择再删除 a[i+1][j-1]
之后,把i和j作为回文串删掉
1 | def min_insertions(st): |
3.27饿了么第一次
1.K小姐的魔法仓库
K小姐是一位魔法师,她拥有三种魔法材料:火焰水晶、海洋之心和风之精灵,分别有 a个、b个和
c个。为了方便使用,她需要将这些材料存放在魔法仓库中,但由于材料的特性,存放时必须遵守以下规则:
每个仓库中的火焰水晶数量不能超过 2个。
每个仓库中的海洋之心数量不能少于 3个。
风之精灵没有特殊要求,可以任意存放。K小姐想知道,最少需要准备多少个仓库,才能将所有材料妥善存放?同时,如果她想尽可能多地使用仓库,最多可以使用多少个?
输入格式
第一行输入一个正整数 g,表示询问的次数。
接下来的 g 行,每行输入三个正整数 a、b、c,分别表示火焰水晶、海洋之心和风之精灵的数量。
输出格式
对于每组询问,输出一行结果。
如果不存在合法的存放方案,则输出 -1。
否则,输出两个正整数,分别表示最少和最多需要的仓库数量,用空格隔开。
示例
输入
2
3 3 3
1 1 1
输出
3 7
-1
思路:
要求最少需要的仓库数量,我们可以这样考虑:
- 先计算出存放火焰水晶所需的最少仓库数,即 []。
- 然后看剩余的海洋之心和风之精灵的总数是否不小于 3,如果小于3,则无解。
- 如果剩余材料总数不小于 3,那么可以将它们都放入一个仓库中,此时仓库总数就是最少需要的仓库数。
要求最多可以使用的仓库数量,我们可以这样考虑:
- 先将海洋之心平均分配到若干个仓库中,每个仓库恰好 3个,计算出需要的仓库数。
- 然后将剩余的海洋之心、火焰水晶和风之精灵各自单独放入一个仓库中。
- 所有仓库的总数就是最多可以使用的仓库数。
1 | def solve(): |
3.K小姐的密码锁
K小姐在研究一个有趣的密码锁问题。这个密码锁由一排按钮组成,每个按钮要么是未知状态(用 ? 表示),要么是已解锁状态(用 * 表示)。对于每个未知状态的按钮,它旁边会标记一个数字(
0到 2),表示其左右两侧已解锁按钮的总数。
现在 K小姐想要知道,一共有多少种可能的解锁方案满足所有按钮旁边的数字条件。由于方案数可能很大,你只需要输出结果除以 的余数即可。
输入格式
输入一行,包含一个只由 *、? 和 0 到 2 组成的字符串,表示密码锁的初始状态。字符串长度不超过
。
输出格式
输出一个整数,表示可能的解锁方案数除以
的余数。
示例
输入
??**2?11??
输出
8
思路
dp,看不会
1 |
3.28携程第一次
😁第一次ak,两题用的双指针,练就有用!
3.游游的区间除2
游游拿到了一个数组,她可以进行最多一次操作:选择一个元素全是偶数的区间,使这个区间所有元素除以2.
游游希望最终所有元素之和尽可能大,你能帮帮她吗?
输入描述
第一行输入一个正整数n,代表数组的大小。
第二行输入n个正整数,代表数组的元素。
输出描述
一个整数,代表最终所有元素之和的最大值。
示例
输入
5
8 -4 2 -6 5
输出
-1
说明
[-4,2,-6]是一个全是偶数的区间,将其除以2后得到[-2,1,-3],最终所有元素之和为-1。
1 | import sys |
4.SQL题
cities
表
city_id: 城市id
city_name: 城市名
country: 国家
city_id | city_name | country |
---|---|---|
1 | 巴黎 | 法国 |
2 | 罗马 | 意大利 |
3 | 东京 | 日本 |
tour_packages
表
package_id: 旅游线路id
city_id: 城市id
package_name: 旅游线路名
start_date: 开始日期
end_date: 结束日期
price: 价格
package_id | city_id | package_name | start_date | end_date | price |
---|---|---|---|---|---|
1 | 1 | 巴黎之旅 | 2023-01-01 | 2023-01-10 | 1000 |
2 | 1 | 巴黎之旅 | 2023-01-11 | 2023-01-20 | 1100 |
3 | 1 | 巴黎之旅 | 2023-01-21 | 2023-01-30 | 1200 |
4 | 2 | 罗马之旅 | 2023-01-01 | 2023-01-10 | 1000 |
5 | 2 | 罗马之旅 | 2023-01-11 | 2023-01-20 | 1100 |
6 | 2 | 罗马之旅 | 2023-01-21 | 2023-01-30 | 1200 |
7 | 3 | 东京之旅 | 2023-01-01 | 2023-01-10 | 1000 |
1 | select |
3.30腾讯第一次
没参加