CF Round599 Div.2

B1. Character Swap (Easy Version)
B2. Character Swap (Hard Version)

题意:给你两个长度为n的字符串s,t,字符串只包含26个小写字母。你的操作是每次从两个字符串中分别挑一个字母出来交换,问能不能使得两个串相等。

  1. 第一问中你只能操作1次(且必须操作1次), n ≤ 10000 n\leq 10000 n10000
  2. 第二问中你最多可以操作 2 n 2n 2n 次, n ≤ 50 n\leq 50 n50

分析:对于第一问,只保留 s,t 中不同的字符。只有形如aa,bb的长度为2的两个串可以在一次交换中完成任务。对于第二问,只要每个字母在两个串中出现的次数和都是偶数就有解;可以证明,最多2次操作就能将当前两个串中第一个不同的字母交换成相同的,总交换次数不超过2n。

C. Tile Painting

题意:在一个1*n的矩形中,如果两个格子 i , j i,j i,j 满足 ∣ i − j ∣ |i-j| ij 是n大于1的约数,这两个格子就要染成相同颜色。问染完所有格子最多用多少种颜色。

分析:1. 如果n是素数,那么任意两个格子都可以不同色。2. 如果n不是素数且只有1个素因子p,那么最多用p种颜色。3. 如果n有多个素因子,所有格子都必须同色。

D. 0-1 MST

题意n个顶点的完全图中所有边权都为0,现将其中m条边权重变为1,问最小生成树的权重,其中 n , m ≤ 1 0 5 n,m\leq 10^5 n,m105

分析:等价于在完全图上删若干条边后求连通分量数。同样有dfs和并查集两种写法。基于dfs的实现见代码

E. Sum Balance

题意:有k个盒子,每个盒子里有若干个数,要求从每个盒子中取出1个数(共k个),再重新分配到k个盒子里,问能不能经过1次这样的操作使得盒子里的数的总和相同。 k ≤ 15 k\leq 15 k15,每个盒子里不超过5000个数,所有的数两两不等。

分析:首先排除所有数总和s不是k的倍数的情况。如果s是k的倍数,那么最后每个盒子里的总和就是avg=s/k。如果第i个盒子当前数字和是Si,移除其中某个数x,我们可以计算出需要补进的数为y=avg-Si+x。由于所有数字两两不同,我们可以用有向图描述x,y之间的关系:每个数是一个顶点,从x引一条有向边到y。注意,来自同一个盒子的两个数之间不能引边,但可以从自己引向自己。在这张图上,一个大小为c的环就代表了c个盒子之间的数字置换。问题转化为能否找到若干个环,这些环覆盖所有的盒子,且没有两个环覆盖同一个盒子。

在实现上,因为数字的唯一性,图上的每个点都只有一条出边,因此所有环都不相交。求出所有的环之后,我们根据环覆盖的盒子情况给环做mask编码。最终答案就是k位全为1的编码能不能由这些mask拼凑出来。这是一个数位动规的问题,在动规的过程中,我们需要求一个编码所有的子编码,核心代码是下面这个两重循环,复杂度为 O ( 3 n ) O(3^n) O(3n),更多细节见代码

for (int i = 1; i < (1<<n); i++) {
    for (int j = i; ; j = (j-1)&i) {
 		// do sth with i, j
 		if (j == 0) break;
 	}
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值