codeforces Round 1021-1030(部分题解)

有些好的题解就直接复制过来了,所以部分非作者所写题解
持续更新中…

Round 1021 (Div. 2)

B.Sasha and the Apartment Purchase(货舱选址变种)

在这里插入图片描述

C.Sports Betting(思维)

在这里插入图片描述
发现对于同一天 a i a_i ai 预测的结果只有 00 , 01 , 10 , 11 00,01,10,11 00,01,10,11,所以只要任意一天的预测人数 > = 4 >=4 >=4,那么就是Yes。
还有一种情况就是当前位置的人数为2或3,以 c n t ( a i ) = 2 cnt(a_i)=2 cnt(ai)=2为例,那么我们不妨预测为01和11,第一天必对一种,然后看第二天,如果 c n t ( a i + 1 ) = 2 cnt(a_i+1)=2 cnt(ai+1)=2,那么分别预测01,00,我们看到了,如果第二天是1,那么成功,如果第二天是0,那么第三天比对一种,肯定是可以成功的。
假设 c n t ( a i + 1 ) = 1 cnt(a_i+1)=1 cnt(ai+1)=1,我们让预测结果为01,然后 c n t ( a i + 2 ) = 1 cnt(a_i+2)=1 cnt(ai+2)=1 预测结果也是01,直到再次遇到 c n t ( a i + k ) > = 2 cnt(a_i+k)>=2 cnt(ai+k)>=2即可。

Round 1022 (Div. 2)

D.Needle in a Numstack(二分+循环节+交互题)

这是一个互动问题。

给定正整数 n , k ( n < = 1 e 5 , k < = 50 ) n,k(n<=1e5,k<=50) n,kn<=1e5,k<=50,两个未知数组 A 和 B满足。
∣ A ∣ + ∣ B ∣ = n |A|+|B|=n A+B=n,数组的总长度为 n。
∣ A ∣ ≥ k , ∣ B ∣ ≥ k |A|≥k,|B|≥k AkBk,每个数组的长度至少为 k。
数组只包含从 1 到 k 的数字。

如果从数组 A 和 B 中任选 k 个连续元素,它们都将是不同的。
先把数组 A 的元素写入数组 C,然后再把数组 B 写入数组C。
可以提出<=250个问题来询问 C i C_i Ci 是多少
您需要找出数组 A 和 B 的长度,或者报告无法唯一确定它们的长度。

因为任意任选 k 个连续元素,它们都将是不同的,所以数组A,B必有周期位k的循环节。
数组左起右起分别是两个周期为 k k k的循环节,我们可以通过这个求出唯一的分界点
首先用 2 k 2k 2k 次查询记录首尾两个循环节。然后用一个 p o s pos pos数组记录下中间段且满足在两个循环节中对应元素值不同的位置(即可能的分界点)。
p o s pos pos 中二分 mid 并查询第 m i d mid mid 位上的值判断属于左循环节还是右循环节,从而逼出可能的答案区间 [ l , r ] [l,r] [l,r]。当且仅当 l + 1 = r l+1=r l+1=r 时有唯一解。

Round 1023 (Div. 2)

A. LRC and VIP

给定大小为 n n n的序列,问你能不能把这个序列分成两个序列,两个序列的 g c d gcd gcd 不同,因为 g c d < = n gcd<=n gcd<=n个数的最大值,所以我们只需要选出最大值放到其中的一个序列中即可,注意判断是否全为最大值。

B.Apples in Boxes

题意: n n n 个数,两个人博弈。每轮一个人选择使得一个 a i a_i ai减一。如果操作后极差大于k则输。如果所有 a i a_i ai都是零那么则无法操作,无法操作的人输。求第一个人能不能赢。

为了保证极差小于等于 k。减最小值肯定不优。那么不减最小值就只能减其它数,随着其它数变小,极差也只会变小。所以如果一开始第一个人不输,则会一直到所有数都变成零才结束,此时如果总和是奇数第一个人就赢。一开始就输的情况就是最大值减一后极差大于 k,或者最大值有多个且极差大于 k

C. Maximum Subarray Sum

题意:给你数组 a a a,有些地方没填。你需要填上后使得最大子段和等于 k 。
先判断无解
有解的情况下,我们只需要选一个填的位置,其他位置填上 − i n f -inf inf即可。

D. Apple Tree Traversing(树的直径)

题意:给你一棵树。每次选择一条路径,路径端点为 u , v u,v u,v。这条路径不能包含选择过的点。如果把 c n t , u , v cnt,u,v cnt,u,v 三个整数加入答案, c n t cnt cnt 是路径上的点数,然后把路径上的点标记为选择过。求字典序最大的答案。

每次找到没有遍历过的树的直径,然后把直径上的所有结点去掉,把树变成森林,然后再处理森林即可,时间复杂度 O ( N ∗ s q r t N ) O(N*sqrtN) O(NsqrtN)

Round 1024 (Div. 2)

A. Dinner Time

题意:给你 n , m , p , q n,m,p,q n,m,p,q 看是否存在 长度为n的数组满足和为m且任何长度为p的子数组和为q。
首先如果 p ∣ n p|n pn 那么只需要判断 n / p ∗ q = = m n/p *q ==m n/pq==m 是否满足即可
如果 p p p 不整除 n n n 那么有 k ∗ p + x = m k*p+x = m kp+x=m ( x x x的长度是 n / p n/p n/p的余数) ,那么最后一段怎么满足呢,只需要前面那段等于 − - x 即可,然后往前推一定能满足题意.

D Quartet Swapping(思维+逆序对)

给定一个长度为 n n n 的排列 a a a ∗ ^{\text{∗}} 。你可以进行以下操作任意次数(包括零次):

  • 选择一个下标 1 ≤ i ≤ n − 3 1 \le i \le n - 3 1in3。然后,同时交换 a i a_i ai a i + 2 a_{i+2} ai+2,以及 a i + 1 a_{i+1} ai+1 a i + 3 a_{i+3} ai+3。换句话说,排列 a a a 将从 [ … , a i , a i + 1 , a i + 2 , a i + 3 , … ] [\ldots, a_i, a_{i+1}, a_{i+2}, a_{i+3}, \ldots] [,ai,ai+1,ai+2,ai+3,] 变为 [ … , a i + 2 , a i + 3 , a i , a i + 1 , … ] [\ldots, a_{i+2}, a_{i+3}, a_i, a_{i+1}, \ldots] [,ai+2,ai+3,ai,ai+1,]

请确定通过任意次上述操作后能得到的字典序最小的排列 † ^{\text{†}}

可以分成奇数下标和偶数下标的两个序列。
找规律可以发现一个数跳偶数次不改变另一序列的顺序,奇数次会改变,所以我们只需要将前m-2小的数排到前面,然后看每个数跳了奇数次还是偶数次,如果为奇数就交换后两个,否则不交换。
在这里插入图片描述

Round 1025 (Div2)

A. It’s Time To Duel

N个人排成一排只和相邻的人战斗,有人会撒谎,让你判断不可能的局面

对于1:不能全是1,因为 n - 1 场战斗最多有 n - 1 个玩家赢。
对于0:相邻两项不能都是0,因为战斗总是有人赢,有人输。

B Slice to Survive(棋盘切割)

一个人负责调整棋子位置,一个人切棋盘。
切棋盘每次只能切掉一边,所以 横向的切 跟 纵向的切 是独立的。
调整棋子位置的人,把棋子放到中间最优,因为这样可以最小化 各种方向切的损失。(偶数个格子就没办法了,总有一边损失大 1 格)。
切棋盘的人,每次切掉的 行数(列数)越多越好。

对于怪物的初始位置,只能影响第一次切。因为结果可以在 log 时间内计算出,我们各个方向都切一遍取最大值也是可以接受的。

n n n 为行(列)的数量。 n n n 为偶数时,能切掉 n / 2 n / 2 n/2,还剩下 n / 2 n / 2 n/2 n n n 为奇数时,能切掉 n / 2 n / 2 n/2,还剩下 ( n + 1 ) / 2 (n + 1) / 2 (n+1)/2。模拟这个切的过程,即 c e i l [ l o g ( n ) ] + c e i l [ l o g ( m ) ] ceil[log(n)]+ceil[log(m)] ceil[log(n)]+ceil[log(m)]

C1. Hacking Numbers (Easy Version)(交互,数学)

交互题目,每次可以进行以下询问
在这里插入图片描述

给定一个 x x x(我们不知道),目的是把这个 x ( < = 1 e 9 ) x(<=1e9) x<=1e9变成 n n n (询问不超过7次)

    digit();//x -> [1-81]
    digit();//-> [1-16]
    add(-8);//-> [1-8]
    add(-4);//-> [1-4]
    add(-2);//-> [1-2]
    add(-1);//-> 1
    mul(n);
	ans();

C2. Hacking Numbers (Mid Version)

很明显如果一个数能被9整除,那么这个数的数位和也能被9整除,先对x乘9,
x ( < = 9 e 9 ) x(<=9e9) x(<=9e9) 然后对 x x x进行一次 d i g i t ( ) ( x − > [ 9 , 89 ] ) digit()(x->[9,89]) digit()(x>[9,89]),再进行一次 d i g i t ( ) ( x − > 9 ) digit()(x->9) digit()(x>9),最后 a d d ( n − 9 ) add(n-9) add(n9)即可。

C3. Hacking Numbers (Hard Version)

mul(999999999);
digit();
if(n!=81)add(n-81);
ans();

D D/D/D

可以发现对于偶数路径的点,都可以通过多次折回来到达,所以只要存在一个大偶数 n n n,即可到达 d i s t dist dist 2 , 4 , 6 , 8 … , n − 2 , n 2,4,6,8…,n-2,n 2,4,6,8,n2,n的所有点,奇数同理,对于一个大奇数 n n n,可到达 d i s t dist dist 1 , 3 , 5 , 7 … , n − 2 , n 1,3,5,7…,n-2,n 1,3,5,7,n2,n的所有点,所以只需要跑一遍 b f s bfs bfs(注意每个状态的奇偶性)即可,然后判断能组成的最大偶数和奇数。

E. Binary String Wowee

组合计数+动态规划(待补)

Round 1026(Div2)

C Racing(线段交)

根据当前的位置算出一个范围,检查该范围是否合法,然后从后往前递推出每次选择的操作。

D. Fewer Batteries(二分答案+dp check)

电池数越多,那么可以到达终点的可能性越大,所以可以二分电池数, c h e c k check check 的时候在 D A G DAG DAG 上做一次简单 d p dp dp 即可算出

Round 1027 (Div. 3)

D. Come a Little Closer’(multiset模拟)

题意:在方格图上给出一堆坐标,你有一次操作机会可以将其中一个坐标移到任意地方,要求你最小化矩阵面积(所有点都要在矩阵内或矩阵上)
使用 m u l t i s e t multiset multiset 分别存储x坐标和y坐标,遍历删除某个点,计算当前矩阵的面是多大,具体就是 ( m x x − m n x + 1 ) × ( m x y − m n y + 1 ) (mxx-mnx+1)×(mxy-mny+1) (mxxmnx+1)×(mxymny+1),特判一下该面积是否等于 n − 1 n-1 n1,如果是那就是 m i n ( ( m x x − m n x + 2 ) × ( m x y − m n y + 1 ) ,( m x x − m n x + 1 ) × ( m x y − m n y + 2 ) ) min((mxx-mnx+2)×(mxy-mny+1),(mxx-mnx+1)×(mxy-mny+2)) min((mxxmnx+2)×(mxymny+1),(mxxmnx+1)×(mxymny+2))

F. Small Operations(约数+暴力dp)

在这里插入图片描述

这道题很妙,可以让 x x x y y y除去他们的 g c d gcd gcd,我们只需要将 x x x除去然后再乘上 y y y即可了。
怎么求呢?我们可以通过埃氏筛的思想将所有数 ( 1 − N ) (1-N) (1N)的约数求出来,然后使用dp,求出 x x x y y y 最少可以用多少个他们的约数凑出来,注意转移的时候有每次乘上的数 < = k <=k <=k,最后的结果就是 f [ x ] + f [ y ] f[x]+f[y] f[x]+f[y]

    auto work = [&](int x){
        //x的所有因子个数
        int m = g[x].size();
        vector<int> f(m,inf);
        f[0]=0;//第一个是1
        for(int i=0;i<m;i++){
            for(int j=i+1;j<m;j++){
                if((g[x][j]%g[x][i]==0)&&(g[x][j]/g[x][i]<=k)){
                    f[j]=min(f[j],f[i]+1);
                }
                else if(g[x][j]/g[x][i]>k){
                    break;
                }
            }
        }
        return f[m-1]==inf?-1:f[m-1];
    };

Round 1028(Div2)

B. Gellyfish and Baby’s Breath(指数比较)

在这里插入图片描述

注意到性质 2 n = = 2 n − 1 + 2 n − 1 2^n == 2^n-1 + 2^n-1 2n==2n1+2n1,所有我们只要求最大的前缀 a j a_j aj b i − j b_{i-j} bij即可,如果相同的话比较第二个数的大小即可。

C. Gellyfish and Flaming Peony(gcd+暴力dp)

题意:给你一个数组,每次选两个数,使得其中数变成它们的 g c d gcd gcd。求所有数变成一样的最小操作数。
显然最后变成的数是整个数组的 g c d gcd gcd。那么应该选最少的数使得可以得到数组的 g c d gcd gcd,那么其它数和这个数操作就一步到位了。问题变为选择最少的数使得它们的 g c d gcd gcd 等于数组的 g c d gcd gcd。观察到 a i < = 5 e 3 a_i<=5e3 ai<=5e3。可以
f [ i ] [ j ] f[i][j] f[i][j]表示前 i i i g c d gcd gcd j j j最少选几个数。使用滚动数组优化一下内存可以通过。

    vector<int> f(mx+1,inf);
    f[a[1]]=1;
    for(int i=2;i<=n;i++){
        for(int j=1;j<=mx;j++){
            if(f[j]==inf)continue;
            f[__gcd(a[i],j)]=min(f[__gcd(a[i],j)],f[j]+1);
        }
        f[a[i]]=1;
    }
    cout<<n-1+f[gd]-1<<'\n';

Round 1029 (Div. 3)

E.Lost Soul(思维+set)

给你两个长度均为n的整数数组a和b。

你可以任意次数执行以下操作:

选择一个索引 i ( 1 ≤ i ≤ n − 1 ) i(1≤i≤n−1) i(1in1),将 a i a_i ai设为 b i + 1 b_{i+1} bi+1,或者将 b i b_i bi​设为 a i + 1 a_{i+1} ai+1

在执行任何操作之前,你可以选择一个索引 ( 1 ≤ i ≤ n − 1 ) (1≤i≤n−1) (1in1),从两个数组中同时移除 a i a_i ai b i b_i bi 。这种移除操作最多只能进行一次。

对于两个长度为m的数组c和d,它们的“匹配数”指的是满足 c j = d j c_j = d_j cj=dj 的位置 j ( 1 ≤ j ≤ m ) j(1 ≤ j ≤ m) j1jm的数量。
你的任务是计算通过操作能达到的最大匹配数。

题解:
1.当 a i = b i a_i=b_i ai=bi 的时候,可以让前i个数相等。
2.当 a i = a i + 1 a_i=a_{i+1} ai=ai+1 b i = b i + 1 b_i=b_{i+1} bi=bi+1的时候,也可以让前i个数相等。
3.我们发现当删除某一个位置i的时候,可以改变后续对前面的影响,即 b i + 1 − > a i − 1 b_{i+1}->a_{i-1} bi+1>ai1或者 a i + 1 − > b i − 1 a_{i+1}->b_{i-1} ai+1>bi1,那么,当我们枚举到某个位置 i i i的时候, a i − 1 a_{i-1} ai1 b i − 1 b_{i-1} bi1可以变成 [ i + 1 , n ] [i+1,n] [i+1,n]的任何一个 a j , b j a_j,b_j ajbj,那么这次的答案就是 i-1
在所有情况下取最大值即可。

Round 1030 (Div. 2)

B.Make It Permutation(思维+找规律)

题意:给你一个 n ∗ n n*n nn的矩阵, A i , j = j A_{i,j}=j Ai,j=j。你每次可以选择某一行将其一个子区间翻转。最多操作2*n次。求每一列都是排列的操作方案。
让斜着的每一排都相等即可。
反转第一行的 [ 1 , n ] [1,n] [1,n]
i i i [ 2 , n ] [2,n] [2,n]的时候翻转 [ 1 , i − 1 ] 和 [ i , n ] [1,i-1]和[i,n] [1,i1][i,n]即可

C很板子的题,按位贪心即可,D.题直接模拟

Educational Round 179 (Rated for Div. 2)

A Energy Crystals

题意:三个数,每次操作使得一个数增加任意数。但要保证任意两个数都有一个数大于等于另一个数的一半。求三个数都变成 x 的最少操作数。

首先把一个数变成 1,那么发现,之后每操作两步就能使得最大值乘二加一。那么需要
的操作数把最大值变成 2*logx ,然后两次操作把另外两个数变成 x,加上一开始的一步,就是 2 * logx +3。

B.Fibonacci Cubes (思维+几何)

在这里插入图片描述
CD很简单不写了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值