Codeforces Round 930 (Div. 2)题解

A. Shuffle Party(Problem - A - Codeforces)

题目大意:给定一个n长数组,并使得a[i]=i,现在定义一种操作swap(k):找出k的最大不等于自己的除数d,交换a[k]和a[d],k从1开始直到n结束,问最后结束的时候1在哪里。

思路:这题的交换看似比较混乱,但是我们如果只盯着1的位置就会发现规律。1可以换到位置2,而位置2只能换到位置4,位置4换到位置8,...,所以实际上我们只要找到n在二进制下最高位1即可。

n在1e9的范围内,我们可以从30开始循环,往低位找。(注意int的数据范围在2^31-1的范围内,所以也就是说int类型的数最多31位,如果从32开始循环就会出现错误)

有两个二进制处理:

获取n的第i位是否是1,判断n>>i&1是否为1,如果为1,就说明n的第i位为1,否则就是0.
将最高位1后面的全部换成0:n>>i<<i,假设n的最高位1在第i位。

#include<bits/stdc++.h>
using namespace std;
int main()
{int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);int flag=1;for(int i=30;i>=0;i--){if(n>>i&1) {flag=n>>i<<i;break;}}printf("%d\n",flag);}
}

 B. Binary Path(Problem - B - Codeforces)

题目大意:现在有一个2行m列的方格阵,每个格子中的值是0或1,我们要从(1,1)到(2,n),每次只能向右或者向下移动一格,问字典序最小的移动方案数。

思路:这题我第一反应就是数字三角形模型+背包问题统计方案数,但也正是因为这个走入了误区,因为很显然这里是每个格子是不能将其中的数视为权重的,如果将0和1视为权重,那么就会出现两种字典序不同的方案最后的花费相同,很显然不符合题意,但是由于我没有跳出第一映像重新分析,就非得找到一个合适的dp的方法,绕来绕去最后实在没辙跑去看第三题了,浪费了不少时间,最后写出来的时候没卡上点。

这题和一般的dp问题不同,因为只能向右或者向下走,所以一旦向下走了就只能向右走了,剩下的步数就只有一种选择了,所以问题的核心在于什么时候向下走。

当我们还在上面的时候,每一步实际面临两种选择,一种是向右走,一种是向下走,字典序相同的时候方案不同那么我们看一下为什么会出现这种情况:

如图,如果三条路径对应的字典序相同,那么标号相同的位置的值必须相同。所以实际上我们只需要找出这样的一段区间即可。那么该怎么找呢,我们可以直接比较这样的格子,也可以比较上面一行向右和向下对应的两个格子是否相等。这里采用第二种方法,因为对输出序列友好一些,然后我们来看具体如何统计:

如果两步操作对应的格子的数是一样的,那么实际上是无所谓的,如果右边是0,下面是1,那么必须向右,前面已经统计的向右向下相等的位置的数目必须作废,如果右边是1,下面是0,那么必须向下,后面的讨论也就没有意义了。所以实际上我们只用一格一格往后找,当向右向下相同的时候计一下数,当两者不同,向右为0的时候重新计数,向下为0的时候直接退出。然后还有一点需要考虑,我们需要输出最后的序列,所以还要统计相等的那一段区间。

#include<bits/stdc++.h>
using namespace std;
char s[3][200010];
int dp[3][200010];
int n;
int main()
{int t;scanf("%d",&t);while(t--){scanf("%d",&n);for(int i=1;i<=2;i++) scanf("%s",s[i]+1);int c=0,i,l=0,r=0;for(i=1;i<n;i++){if(s[1][i+1]==s[2][i]) c++,r++;else if(s[1][i+1]>s[2][i]) break;else c=0,r=l=i+1;}if(i<=n){for(int j=1;j<=i;j++) printf("%c",s[1][j]);for(int j=i;j<=n;j++) printf("%c",s[2][j]);}else{printf("%s",s[1]+1);printf("%c",s[2][n]);}printf("\n%d\n",c+1);}
}

C. Bitwise Operation Wizard(Problem - C - Codeforces)

题目大意:这题是交互题,实际上想让我们实现的是,通过询问若干次a|b与c|d的大小,进而找出异或值最大的两个数。

思路:这题也是我最开始的分析太过片面了,我只考虑了高位1,两个数的异或值大就说明两个数高位是不同的,a|b>c|d,就说明我们可以从a,b中选一个实际生效的数,从c,d中选一个没在|运算高位1中生效的数,然后就此推断出找出最大值和最小值进行异或,但是我忽略了1111111101,01,10这种情况。这种情况下显然选01不如选10。那么这道题该如何考虑呢?

我们还是想办法从这道题的特殊的地方入手,题目中给的数组是一个排列,从0到n-1的排列,那么最大的数显然是n-1,然后要找出n-1为0的哪些位置为1的数,显然两者进行|运算的值应该最大,但是如果仅仅是找或运算的话,那么n-1为1的位置,且找到的数对应位置也为1的位置的那种值如何排除呢,显然我们的目标值中1的个数最少,目标值为1的位置所有找到的值对应的位置应该也是1,但是应该比目标值大。所以就要找到所以值中最小的一个。比较两个数的大小可以通过询问a,a,b,b来得到。

#include<bits/stdc++.h>
using namespace std;
int main()
{int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);if(n==2){printf("! 0 1\n"),fflush(stdout);}else{char op[2];int mx=0,mi=0;//找最大值for(int i=1;i<n;i++){printf("? %d %d %d %d\n",mx,mx,i,i),fflush(stdout);scanf("%s",op);if(op[0]=='<') mx=i; }for(int i=1;i<n;i++){printf("? %d %d %d %d\n",mx,mi,mx,i),fflush(stdout);scanf("%s",op);if(op[0]=='<') mi=i;else if(op[0]=='=') {printf("? %d %d %d %d\n",mi,mi,i,i),fflush(stdout);scanf("%s",op);if(op[0]=='>') mi=i;} }printf("! %d %d\n",mx,mi),fflush(stdout);}}
}

D. Pinball(Problem - D - Codeforces)

题目大意:有一排格子,每个格子中只有'<'和'>'两种字符,有一个小球被放入了第i个格子,如果格子中是'<'那么小球下一秒就会往左移动一格,同时当前格子的字符变成'>',另一种字符同理,问小球放在每个格子的时候离开格子需要多少秒。(1<=n<=5e5)

思路:如果可以模拟的话显然这题不太难,但是n的数据范围太大了,而且还有多组测试样例,很显然不能通过模拟来写,那么就要找一下规律了。

我们先只来看相邻的两个格子,而且将小球放在第一个格子处,

如果是>>,直接向右两步

如果是<<,直接向左一步

如果是><,向右一步,向左两步

如果是<>,直接向左一步。

很显然对于同向的格子可以一直沿着这个方向往前,对于反向的格子>>>><,第一次走到反向位置时,会发现已经变成了<<<<<,所以又可以一直往左。

><<<>>><

>>>>>>><

<<<<<<<<

<<<>>><

抽象一下,如果走到反向位置后,相当于可以将反向位置同化,最后至少有一端是全部被同向化了。起始方向的方向需要统计反向的个数,起始反向的方向需要统计同向个数

统计位置和(下标和处理一下)与个数

两个方向都统计一下

如果是>的话,那么要么左右阻碍个数相同,从右边出,要么左边的阻碍比右边少1个,从左边出

如果是<的话,要么左右阻碍个数相同,从左边出,要么右边的阻碍比左边少1个,从右边出

多余的阻碍可以不用考虑。

>:

cntl[i]>=cntr[i]:左右各考虑最近的cntr[i]个阻碍

cntl[i]<cntr[i]:左边考虑cntl[i]个阻碍,右边考虑最近的cntl[i]+1个阻碍

<:

cntl[i]<=cntr[i]:左右各考虑最近的cntl[i]个阻碍

cntl[i]>cntr[i]:右边考虑cntr[i]个阻碍,左边考虑最近的cntr[i]+1个阻碍,

倒是可以用单调队列统计,

看上去要实现对应位置的查找很麻烦,但实际上我们可以用前缀和+二分的思想来实现。

尽管如此细节处理还是很麻烦。

#include<bits/stdc++.h>
using namespace std;
#define int long long
char s[500010];
int l[500010],r[500010];
int cntl[500010],cntr[500010];
signed main()
{int t;scanf("%lld",&t);while(t--){int n;scanf("%lld",&n);scanf("%s",s+1);for(int i=1;i<=n;i++){if(s[i]=='>'){cntl[i]=cntl[i-1],cntr[i]=cntr[i-1]+1;l[i]=l[i-1],r[i]=r[i-1]+i;}else//<{cntl[i]=cntl[i-1]+1,cntr[i]=cntr[i-1];l[i]=l[i-1]+i,r[i]=r[i-1];}}int ans;for(int i=1;i<=n;i++){if(s[i]=='>'){//右边的<     左边的> if(cntl[n]-cntl[i]<=cntr[i-1])//从右边出,那么左边的>不会用完{//找到左边第cntl[n]-cntl[i]个>int x=cntl[n]-cntl[i];int xl=1,xr=i-1,p=xl;if(x==0) p=i;//这里会出现为0的情况else{while(xl<xr){int mid=(xl+xr)/2;if(cntr[i-1]-cntr[mid-1]<x) xr=mid-1;else if(cntr[i-1]-cntr[mid-1]>x) xl=mid+1;else xl=xr=mid;}p=xl;}//[mid,i-1]这个区间中的>ans=2*(l[n]-l[i]-x*i) + 2*(x*i-(r[i-1]-r[p-1])) + (n-i+1);}else//从左边出,需要获得右边第cntr[i-1]+1个<的位置{int x=cntr[i-1]+1;int xl=i+1,xr=n,p=xl;while(xl<xr){int mid=(xl+xr)/2;if(cntl[mid]-cntl[i]<x) xl=mid+1;else if(cntl[mid]-cntl[i]>x) xr=mid-1;else p=xl=xr=mid;}p=xl;ans = 2*(i*cntr[i-1]-r[i-1])+2*(l[p]-l[i]-(cntl[p]-cntl[i])*i)+i;}}//><<else//<{//左边的> 右边的<if(cntr[i]<=cntl[n]-cntl[i])//从左边出{//获取右边第cntr[i]个<的位置int x=cntr[i];int xl=i,xr=n,p=xl;while(xl<xr){int mid=(xl+xr)/2;if(cntl[mid]-cntl[i]<x) xl=mid+1;else if(cntl[mid]-cntl[i]>x) xr=mid-1;else p=xl=xr=mid;}p=xl;ans=2*(x*i-r[i])+2*(l[p]-l[i]-x*i)+i;}else//从右边出,这里不会出现某种值为0的情况{//找左边第cntl[n]-cntl[i]个>的位置int x=cntl[n]-cntl[i]+1;int xl=1,xr=i-1,p=xl;while(xl<xr){int mid=(xl+xr)/2;if(cntr[i-1]-cntr[mid-1]<x) xr=mid-1;else if(cntr[i-1]-cntr[mid-1]>x) xl=mid+1;else p=xl=xr=mid;}p=xl;ans = 2*(x*i-(r[i-1]-r[p-1]))+2*(l[n]-l[i]-i*(x-1))+n-i+1;}}printf("%lld ",ans);}printf("\n");}
}

总结:b,c两道题都给了一个启示,看到题目先从普遍的情况去思考,当卡住的时候,不要咬死不放,想办法从这道题目特殊的地方再去思考一下。d题的启示在于从某个范围中紧邻的第x个符合要求的数的时候可以考虑前缀和+二分来实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/501954.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

灯塔:HTML笔记

网页由哪些部分组成&#xff1f; *文字 图片 音频 视频 超链接 程序员写的代码是通过浏览器转换成网页的 五大浏览器有哪些&#xff1f; *IE浏览器 *火狐浏览器&#xff08;Firefox&#xff09; *谷歌浏览器&#xff08;Chrome&#xff09; *Safari浏览器 *欧朋浏览器&…

基于CVX凸优化的电动汽车充放电调度matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 CVX凸优化 4.2 电动汽车充放电调度 5.完整程序 1.程序功能描述 基于CVX凸优化的电动汽车充放电调度.仿真输出无电动汽车充电时的负载&#xff0c;电动汽车充电时cvx全局优化求解后的总…

LaMa Image Inpainting 图像修复 Onnx Demo

目录 介绍 效果 模型信息 项目 代码 下载 LaMa Image Inpainting 图像修复 Onnx Demo 介绍 gihub地址&#xff1a;https://github.com/advimman/lama &#x1f999; LaMa Image Inpainting, Resolution-robust Large Mask Inpainting with Fourier Convolutions, WAC…

大模型量化技术原理-ZeroQuant系列

近年来&#xff0c;随着Transformer、MOE架构的提出&#xff0c;使得深度学习模型轻松突破上万亿规模参数&#xff0c;从而导致模型变得越来越大&#xff0c;因此&#xff0c;我们需要一些大模型压缩技术来降低模型部署的成本&#xff0c;并提升模型的推理性能。 模型压缩主要分…

Manacher

Manacher #include<bits/stdc.h> using namespace std; ​ const int N 1e6 9; char s[N]; int p[N]; int mian() {cin >> s 1;int n strlen(s 1);for (int i 2 * n 1; i > 1; --i)s[i] (i & 1) ? # : s[i >> 1];s[0] ^, s[2 * n 2] $;in…

使用Python语言实现一个基于动态数组的序列队列

一、动态数组的实现 首先&#xff0c;我们需要创建一个DynamicArray类&#xff0c;该类将管理我们的动态数组。 动态数组能够动态地调整其大小&#xff0c;以容纳更多的元素。 目录 一、动态数组的实现 代码示例&#xff1a; 二、序列队列的实现 接下来&#xff0c;我…

Redis 在 Linux 系统下安装部署的两种方式详细说明

小伙伴们好&#xff0c;欢迎关注&#xff0c;一起学习&#xff0c;无限进步 Redis安装和配置 1、首先在官网下载好redis-6.0.9.tar.gzhttp://redis.io/ 或者使用 wget 命令下载&#xff1a;wget http://download.redis.io/releases/redis-6.0.9.tar.gz 2、下载使用上传到阿里…

力扣每日一题 使二叉树所有路径值相等的最小代价 满二叉树 贪心

Problem: 2673. 使二叉树所有路径值相等的最小代价 文章目录 思路复杂度Code 思路 &#x1f468;‍&#x1f3eb; 灵神题解 复杂度 ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( 1 ) O(1) O(1) Code class Solution {public int minIncrements(int …

笑营宝高校选修课报名考勤系统源码开发方案

一、项目背景与目标 &#xff08;一&#xff09;项目背景 随着高等教育的普及和教学模式的不断创新&#xff0c;高校选修课程体系日趋复杂多变。学生对课程选择的自由度提高&#xff0c;使得传统的选课和考勤管理方式变得繁琐且效率低下。目前&#xff0c;许多高校仍然采用纸…

2024年【A特种设备相关管理(电梯)】考试总结及A特种设备相关管理(电梯)证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年A特种设备相关管理&#xff08;电梯&#xff09;考试总结为正在备考A特种设备相关管理&#xff08;电梯&#xff09;操作证的学员准备的理论考试专题&#xff0c;每个月更新的A特种设备相关管理&#xff08;电梯…

【已解决】卸载软件时显示“无法使用此产品的安装源,请确认安装源存在,并且你可以访问它”报错截图如下

卸载软件时显示“无法使用此产品的安装源&#xff0c;请确认安装源存在&#xff0c;并且你可以访问它”报错截图如下 使用Uninstall Tool软件强制删除&#xff0c;绕过软件自带的uninstall程序。&#xff08;小白推荐&#xff0c;如下图&#xff09; Uninstall Tool - Unique…

羊大师分析,羊奶和牛奶那种更适合国人的口味?

羊大师分析&#xff0c;羊奶和牛奶那种更适合国人的口味&#xff1f; 羊奶奶和牛奶在口味上确实存在一些差异&#xff0c;哪种更适合中国人的口味可能因人而异。 一般来说&#xff0c;羊奶的味道相对较淡&#xff0c;带有一些特有的膻味&#xff0c;但这种膻味在经过现代除膻…