Codeforces Round 930 (Div. 2)(A,B,C,D)

比赛链接

C是个交互,D是个前缀和加二分。D还是很难写的。


A. Shuffle Party

题意:

您将得到一个数组 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,,an 。最初,每个 1 ≤ i ≤ n 1 \le i \le n 1in 对应 a i = i a_i=i ai=i 。整数 k ≥ 2 k \ge 2 k2 的运算 swap ( k ) \texttt{swap}(k) swap(k) 定义如下:

  • d d d 是不等于 k k k 本身的 k k k 的最大除数 † ^\dagger

然后交换元素 a d a_d ad a k a_k ak

假设您按此顺序对每个 i = 2 , 3 , … , n i=2,3,\ldots, n i=2,3,,n 执行 swap ( i ) \texttt{swap}(i) swap(i) 。在结果数组中查找 1 1 1 的位置。

换句话说,在执行这些操作之后,找到这样的 j j j,满足 a j = 1 a_j = 1 aj=1 † ^\dagger 如果存在整数 z z z 使得 y = x ⋅ z y = x \cdot z y=xz ,则整数 x x x y y y 的除数。

思路:

手玩一下其实比较容易看出来性质。我们只关注 1 1 1 的移动情况,一开始第 1 1 1 个位置和第 2 2 2 个位置交换位置,然后是第 2 2 2 个位置和第 4 4 4 个位置交换位置,移动路径是 1 → 2 → 4 → 8 → … 1\rightarrow2\rightarrow4\rightarrow8\rightarrow\dots 1248

思考一下为什么。因为 2 2 2 是最小的质因数,所以 x x x 第一个被后面交换的数就是 2 ∗ x 2*x 2x。换句话说就是对一个位置,我们交换的是这个位置的最大约数,反过来就是某个数最先会被它的最小倍数交换一次。

因此答案就是 ≤ n \le n n 的最大的 2 2 2 的幂。

code:

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;int T,n;int main(){cin>>T;while(T--){cin>>n;cout<<(1<<(int)(log2(n)))<<endl;}return 0;
} 

B. Binary Path

题意:

您将得到一个由0和1填充的 2 × n 2 \times n 2×n 网格。设第 i i i 行与第 j j j 列的交点处的数字为 a i j a_{ij} aij 。在左上角的单元格 ( 1 , 1 ) (1, 1) (1,1) 中有一只蚱蜢,它只能向右或向下跳一个单元格。它希望到达右下角的单元格 ( 2 , n ) (2, n) (2,n)

考虑长度为 n + 1 n+1 n+1 的二进制串,它由写在路径的单元格中的数字组成,而不改变它们的顺序。

您的目标是:

  1. 通过选择任何可用的路径,查找您可以获得的字典序最小的 † ^\dagger 字符串

  2. 找出产生这个字典序最小字符串的路径数。

† ^\dagger 如果两个字符串 s s s t t t 的长度相同,则 s s s 在字典序上小于 t t t 当且仅当在 s s s t t t 不同的第一个位置,字符串 s s s 的元素比 t t t 中的对应元素小。

思路:

考虑怎样才能得到字典序最小的字符串路径。因为我们只能向下走一步,不能向上走,其他时候都是向右走,所以我们只要找到这个拐点就可以了。

考虑在第一行走的时候什么时候要拐弯。如果我们现在在 ( 1 , i ) (1,i) (1,i),那么右边和下边有三种情况。

  1. 右边是 1 1 1,下边是 0 0 0。这时必须走下边。
  2. 右边是 0 0 0,下边是 1 1 1。这时必须走右边。
  3. 右边和下边一样。这时走哪里都可以。

发现我们最保险的行走策略就是贪心地向右走,直到不得不向下走才拐弯。但是这样只能找到一种可行的行走方案。

发现我们在不得不拐弯之前可能有一段是走哪里都可以的点,有一个点就会产生一种可行的行走方案,所以我们统计一下在最保险的行走方案的拐点前面有多少走哪里都可以的拐点个数即可。

code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int maxn=2e5+5;int T,n;
string mp[3];int main(){cin>>T;while(T--){cin>>n>>mp[1]>>mp[2];mp[1]=" "+mp[1];mp[2]=" "+mp[2];int cnt=0;string str;for(int i=1;i<=n;i++){if(i==n){str=mp[1].substr(1,i)+mp[2].substr(i,n);cnt++;break;}if(mp[1][i+1]=='0'){if(mp[2][i]=='1')cnt=0;else cnt++;}else {if(mp[2][i]=='0'){str=mp[1].substr(1,i)+mp[2].substr(i,n);cnt++;break;}else cnt++;}}cout<<str<<endl<<cnt<<endl;}return 0;
}

C. Bitwise Operation Wizard

题意:

这是一个交互问题。

有一个秘密序列 p 0 , p 1 , … , p n − 1 p_0, p_1, \ldots, p_{n-1} p0,p1,,pn1 ,它是 { 0 , 1 , … , n − 1 } \{0,1,\ldots,n-1\} {0,1,,n1} 的一个排列。

您需要找到任意两个索引 i i i j j j ,使得 p i ⊕ p j p_i \oplus p_j pipj 最大,其中 ⊕ \oplus 表示 按位异或。

为此,您可以询问查询。

每个查询都具有以下形式:选择任意索引 a a a b b b c c c d d d 0 ≤ a , b , c , d < n 0 \le a,b,c,d \lt n 0a,b,c,d<n )。接下来,检验程序将计算 x = ( p a ∣ p b ) x = (p_a \mid p_b) x=(papb) y = ( p c ∣ p d ) y = (p_c \mid p_d) y=(pcpd) ,其中 ∣ | 表示 按位或。最后,您将收到 x x x y y y 之间的比较结果。换句话说,您被告知是否 x < y x \lt y x<y x > y x \gt y x>y x = y x = y x=y 。请查找任意两个索引 i i i j j j 0 ≤ i , j < n 0 \le i,j \lt n 0i,j<n ),使得 p i ⊕ p j p_i \oplus p_j pipj 在所有此类对中最大,最多使用 3 n 3n 3n 个查询。

如果有多对索引满足条件,则可以输出其中的任何一对。

思路:

先想一想 p i ⊕ p j p_i \oplus p_j pipj 的最大值是什么,不难想到应该是 n − 1 n-1 n1 的最高位二进制位和它所有低位的二进制位全部置为 1 1 1 时的数,形式化地讲,假设 n − 1 n-1 n1 的最高位二进制位是第 x x x 位,那么异或的最大值就是 2 x + 1 − 1 2^{x+1}-1 2x+11

那么我们应该怎么得到这个最大值,也不难想,首先找到一个至少最高位二进制位为 1 1 1 的数,再找到一个正好和它互补的另一个数,这样异或出来就是最大值了。因为第二个数的最高位为 0 0 0,所以这个数一定小于第一个数,再加上第一个数我们可以选择不超过 n − 1 n-1 n1 的数,因此两个数我们一定是可以找得到的。

咋找呢,发现两个相同的数 或的结果 是这个数本身,所以我们令 a = b = p i , c = d = p j a=b=p_i,c=d=p_j a=b=pi,c=d=pj,这就相当于比较 p i , p j p_i,p_j pi,pj 的大小了。因此用这种方法可以用 n − 1 n-1 n1 次比较找到最大或者最小值。我们找到 p p p 中的最大值,这个最大值至少最高位二进制位为 1 1 1,这样我们就找到了其中一个数。

然后问题来了,询问的结果返回的是或的结果,而我们需要的是异或的结果,拿我们怎么找到另一个正好互补的数呢。发现 我们找到的数和另一个数或出来的结果是 2 x + 1 − 1 2^{x+1}-1 2x+11 的所有满足条件的另一个数中,正好互补的那个数是最小的

所以我们可以先把所有满足 或的结果是最大值 的另一个数找出来,然后再在这些数里找最小值即可。

code:

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;int T,n;
char st;int main(){cin>>T;while(T--){cin>>n;int idx=0;//找到n-1的位置 for(int i=1;i<n;i++){cout<<"? "<<idx<<" "<<idx<<" "<<i<<" "<<i<<endl;cin>>st;if(st=='<')idx=i;}vector<int> a;a.push_back(0);for(int i=0;i<n;i++){if(i==idx)continue;cout<<"? "<<idx<<" "<<a[0]<<" "<<idx<<" "<<i<<endl;cin>>st;if(st=='<'){a.clear();a.push_back(i);}else if(st=='=')a.push_back(i);}int idx2=a[0];for(auto x:a){cout<<"? "<<idx2<<" "<<idx2<<" "<<x<<" "<<x<<endl;cin>>st;if(st=='>')idx2=x;}cout<<"! "<<idx<<" "<<idx2<<endl;}return 0;
}

D. Pinball

题意:

有一个长度为 n n n 的一维网格。网格的第 i i i 个单元格包含字符 s i s_i si ,该字符为“<”或“>”。当弹球被放置在其中一个单元上时,它根据以下规则移动:

  • 如果弹球在第 i i i 个单元格上且 s i s_i si 是’<‘,那么弹球在下一秒钟向左移动一个单元格。如果 s i s_i si 是’>',它将向右移动一个单元格。

  • 在弹球移动后,字符 s i s_i si 被反转(比如如果 s i s_i si 曾经是’<‘,它就会变成’>',反之亦然)。

  • 弹球从左边界或从右边界离开网格时停止移动。

您需要回答 n n n独立查询。在第 i i i 个查询中,将在第 i i i 个单元格上放置一个弹球。请注意,我们总是在初始网格上放置一个弹球。

对于每个查询,计算弹球离开网格所需的秒数。可以证明,弹球总是在有限的步数内离开网格。

思路:

看视频可能会比较好理解

对傻逼二分一点好感都没有。之前调一道二分题调到凌晨三四点调不出来,中间父母一直在吵架,完全没心情想题,结果觉也没睡好,白天还要赶火车,还晕车。

先手玩一下,发现弹球向一个方向走的时候,如果箭头都是顺着它行走的方向,那么弹球就可以一直走下去,直到遇到第一个反方向的箭头(左边的小于号,右边的大于号),它就会被打回来,这时,小球之前走过的路线因为刚刚方向翻转了,小球就可以畅通无阻地走回起点,然后再向起点另一边走。而且第一个反方向的箭头也被消除了,加入到了前面那段畅通无阻的路线,等到下次再走这一边的时候就可以向右边更远的地方行走。

小球就这样来来回回地走,左边每有一个大于号,小球就会在左边被弹回来一次,同理,右边每有一个小于号,小球就会在右边被弹回来一次,弹来弹去,肯定有一边的反方向箭头不够用,然后小球就会在这边走出边界。那么在哪边走出去呢?两边各消耗了几个反方向箭头?

不妨设左边的大于号的个数为 gn \texttt{gn} gn,右边小于号的个数为 ln \texttt{ln} ln。若弹球最后从左边界弹出,说明右边的小于号很多。若:

  1. 初始方向向右,那么需要满足 l n > g n ln>gn ln>gn,这时实际会使用 g n + 1 gn+1 gn+1 个右边小于号。
  2. 初始方向向左,那么需要满足 l n > = g n ln>=gn ln>=gn,这时实际会使用 g n gn gn 个右边小于号。

其他情况就是从右边界弹出的情况,若:

  1. 初始方向向左,那么需要满足 g n > l n gn>ln gn>ln,这时实际会使用 l n + 1 ln+1 ln+1 个右边小于号。
  2. 初始方向向右,那么需要满足 g n > = l n gn>=ln gn>=ln,这时实际会使用 l n ln ln 个右边小于号。

知道了来回弹了几次,从哪个边界出去了,那么怎么计算步数呢?

我们看一下小球移动的路径,发现路径可以看成:若干个 小球从起点走到一边的反方向箭头再回到起点 的段相接,最后再加上一个从起点走出边界的段即可。而小球从起点走到某个方向的反方向箭头,然后再回到起点的长度,其实就相当于两倍的起点到这个箭头的距离。请添加图片描述

假设我们向右走,起点在 i i i,右边的第 j j j 个反方向箭头位置为 i d x j idx_j idxj,实际使用了 l n ln ln 个箭头。单个的箭头我们可以直接算,就是 i d x j − i idx_j-i idxji。如果多个箭头同时计算,相当于 ∑ k i d x k − i ∗ l n \sum_kidx_k-i*ln kidxkiln。我们可以使用前缀和维护前面的东西,这样就可以 O ( 1 ) O(1) O(1) 查询一边的多个箭头的路径。起点右边也可以这样处理(可以正着算前缀和,也可以反着算也就是后缀和 ,我是反着来算的,这样写法上比较对称),这样两边各查询一遍,再加上从起点走出边界的那段就是答案了。

不过处理出了前缀和,我们知道有一边可能用不掉所有箭头,我们需要找到实际用到的箭头的位置,查询它的前缀和才对,这就需要二分查找了。

code:

这里第47行重载了二分查找的比较函数,从而实现了自定义规则的二分查找。具体用法可以参考:讲解

这里的 [](ll val,ll ele)->bool{return ele<val;} 实现的功能 是二分查找第一个小于 v a l u e value value 的位置,然后后面 -sg-1 得到的就是最后一个大于等于 v a l u e value value 的位置。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=5e5+5;
typedef long long ll;int T,n;
char str[maxn];ll sl[maxn],sg[maxn],s1[maxn],s2[maxn];int main(){cin>>T;while(T--){cin>>n>>str+1;sl[0]=s1[0]=sg[n+1]=s2[n+1]=0;for(int i=1;i<=n;i++){sl[i]=sl[i-1]+(str[i]=='<');s1[i]=s1[i-1]+(str[i]=='<')*i;}for(int i=n;i>=1;i--){sg[i]=sg[i+1]+(str[i]=='>');s2[i]=s2[i+1]+(str[i]=='>')*(n-i+1);}//		for(int i=1;i<=n;i++)cout<<sl[i]<<" \n"[i==n];
//		for(int i=1;i<=n;i++)cout<<sg[i]<<" \n"[i==n];
//		for(int i=1;i<=n;i++)cout<<s1[i]<<" \n"[i==n];
//		for(int i=1;i<=n;i++)cout<<s2[i]<<" \n"[i==n];
//		cout<<endl;for(ll i=1,ln,gn,idx;i<=n;i++){ln=sl[n]-sl[i];//右边小于号数量 gn=sg[1]-sg[i];//左边大于号数量 if((str[i]=='>' && ln>gn) || (str[i]=='<' && ln>=gn)){//右边小于号太多了,从左边界弹出 if(str[i]=='>')ln=gn+1;//实际用到的小于号数量 else ln=gn;idx=lower_bound(sl+i,sl+n+1,ln+sl[i])-sl;cout<<(s1[idx]-s1[i]-1ll*i*ln+s2[1]-s2[i]-1ll*(n-i+1)*gn)*2+i<<" ";}else {if(str[i]=='<')gn=ln+1;//实际用到的大于号数量 else gn=ln;idx=upper_bound(sg+1,sg+i+1,gn+sg[i],[](ll val,ll ele)->bool{return ele<val;})-sg-1;cout<<(s1[n]-s1[i]-1ll*i*ln+s2[idx]-s2[i]-1ll*(n-i+1)*gn)*2+(n-i+1)<<" ";}}cout<<endl;}return 0;
}

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

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

相关文章

win10 禁止谷歌浏览器自动更新(操作贼简单)

禁止谷歌浏览器自动更新 &#xff08;1&#xff09;修改 "C:\Windows\System32\drivers\etc\hosts 文件&#xff0c;在最后增加 127.0.0.1 update.googleapis.com&#xff08;2&#xff09;保存后&#xff0c;winr 快捷键&#xff0c;输入cmd &#xff0c;打开命令行 &am…

AJAX踩坑指南(知识点补充)

JWT JSON Web Token是目前最为流行的跨域认证解决方案 如何获取&#xff1a;在使用JWT身份验证中&#xff0c;当用户使用其凭据成功登录时&#xff0c;将返回JSON Web Token(令牌&#xff09; Token本质就是一个包含了信息的字符串 如何获取Token:登录成功之后&#xff0c;服务…

Springboot解决跨域问题方案总结(包括Nginx,Gateway网关等)

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 前言 解决跨域问题方案 1.Spring Boot 中解决跨域 1.1 通过注解跨域 1.2 通…

什么是RabbitMQ的死信队列

RabbitMQ的死信队列&#xff08;Dead Letter Queue&#xff0c;简称DLQ&#xff09;是一种用于处理消息失败或无法路由的消息的机制。它允许将无法被正常消费的消息重新路由到另一个队列&#xff0c;以便稍后进行进一步处理、分析或排查问题。 当消息对立里面的消息出现以下几…

深度学习基础之《TensorFlow框架(10)—案例:实现线性回归(2)》

增加其他功能 一、增加变量显示 1、目的&#xff1a;在TensorBoard当中观察模型的参数、损失值等变量值的变化 2、收集变量 不同的变量要用不同的方式收集 &#xff08;1&#xff09;tf.summary.scalar(name, tensor) 收集对于损失函数和准确率等单值变量&#xff0c;name为…

Spring Boot 自动化单元测试类的编写过程

前言 Web环境模拟测试 企业开发不仅要保障业务层与数据层的功能安全有效&#xff0c;也要保障表现层的功能正常。但是我们一般对表现层的测试都是通过postman手工测试的&#xff0c;并没有在打包过程中代码体现表现层功能被测试通过。那么能否在测试用例中对表现层进行功能测…

LabVIEW高效光伏数据监控与管理系统

LabVIEW高效光伏数据监控与管理系统 随着新能源技术的发展&#xff0c;光伏发电系统作为一种清洁、高效的能源获取方式受到了广泛的关注。但是&#xff0c;由于光伏发电的特性受到多种环境因素的影响&#xff0c;其运行效率和安全性成为了关键问题。因此&#xff0c;开发一个高…

K8S--SpringCloud应用整合Nacos实战

原文网址&#xff1a;K8S--SpringCloud应用整合Nacos实战-CSDN博客 简介 本文介绍K8S部署SpringCloud应用整合Nacos实战。 本文是将原来的SpringCloud项目&#xff08;闪速优选&#xff09;迁移到K8S上&#xff0c;一行代码都不需要改动。用K8S运行Nacos、Gateway、SpringCl…

Mac nvm install failed python: not found

报错 $>./configure --prefix/Users/xxx/.nvm/versions/node/v12.22.12 < ./configure: line 3: exec: python: not found nvm: install v12.22.12 failed!解决方法 到 App 文件夹&#xff0c;并且打开 cd /System/Applications/Utilities/ open .记得改完 Rosetta 之…

模拟-算法

文章目录 替换所有的问号提莫攻击Z字形变换外观数列数青蛙 替换所有的问号 算法思路&#xff1a; 从前往后遍历整个字符串&#xff0c;找到问号之后&#xff0c;就遍历 a ~ z 去尝试替换即可。 class Solution {public String modifyString(String s) {char[] ss s.toCharA…

mac下 3.6.3 版本 maven

问题 Blocked mirror for repositories: [snapshots (http://xxx/artifactory/gm-maven-vir, default, releasessnapshots)]无法访问 Maven 3.8.1 http 仓库。可能的解决方案: - 检查 Maven settings.xml 是否不包含 http 仓库 - 检查 Maven pom 文件是否不包含 http 仓库 htt…

bs4的基本使用

下载基本使用标签定位标签属性定位选择器定位数据的提取 下载 pip install bs4 pip install lxml基本使用 from bs4 import BeautifulSoup #1.创建一个BeautifulSoup的工具对象&#xff0c;然后把即将被解析的页面源码数据加载到该对象中#参数1&#xff1a;被解析的页面源码数…

【STM32嵌入式系统设计与开发】——6矩阵按键应用(4x4)

这里写目录标题 一、任务描述二、任务实施1、SingleKey工程文件夹创建2、函数编辑&#xff08;1&#xff09;主函数编辑&#xff08;2&#xff09;LED IO初始化函数(LED_Init())&#xff08;3&#xff09;开发板矩阵键盘IO初始化&#xff08;ExpKeyBordInit()&#xff09;&…

【管理咨询宝藏56】大型德企业务战略规划报告

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏56】大型德企业务战略规划报告 【格式】PDF 【关键词】战略规划、商业分析、管理咨询 【核心观点】 - 这是一份非常完整的知名德企在华业务战略…

7-Zip 23.00 beta以上版本的压缩包兼容性问题

7-Zip 23.00 beta加入了ARM64 filter&#xff0c;7-Zip 24.02 beta加入了RISCV filter&#xff0c;这两个filter不能在之前的版本解压&#xff0c;这两个filter目前只适用于ARM64/RISCV的扩展名是exe/dll的可执行文件&#xff0c;其中ARM64的exe/dll目前比较常见&#xff0c;RI…

【Linux实践室】Linux用户管理实战指南:新建与删除用户操作详解

&#x1f308;个人主页&#xff1a;聆风吟_ &#x1f525;系列专栏&#xff1a;Linux实践室、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️任务描述二. ⛳️相关知识2.1 &#x1f514;Linux创建用户命令2.1.1 知识点讲解2.1.2 案…

基于python+vue大学生兼职管理系统flask-django-php-nodejs

本系统在设计过程中&#xff0c;很好地发挥了该开发方式的优势&#xff0c;让实现代码有了良好的可读性&#xff0c;而且使代码的更新和维护更加的方便&#xff0c;操作简单&#xff0c;对以后的维护减少了很多麻烦。系统的顺利开发和实现&#xff0c;对于大学生兼职管理这一方…

485问题汇总

485问题汇总 485 通信波形没有负电压 问题描述&#xff1a;设备在没有外设的时候通信波形是正常的&#xff0c;即5V可以出来&#xff0c;在连接上设备后&#xff0c;设备的通信波形的-5V会随着设备的增多&#xff0c;电压会慢慢上升。当设备连接到24台设备后&#xff0c;485总…

MySQL下载及安装过程

MySQl 5.7 安装图解 目录 MySQl 5.7 安装图解 第一步 安装包 第二步 Mysql协议 第三步 安装前检查 第四步 安装 第五步 产品配置 第六步 安装完成 第一步 安装包 双击安装包文件 进行安装 第二步 Mysql协议 同意Mysql协议 , 选择 Server Only安装Mysql服务器即可 …

数据结构(三)复杂度的深层次剖析

之前发布了数据结构&#xff08;一&#xff09;&#xff0c;很多同学反响不够清晰&#xff0c;那今天就发一篇对复杂度专题的博客&#xff0c;希望对大家理解复杂度提供一些帮助。 时间复杂度 我们先来一个理解一个复杂度&#xff0c;二分查找的复杂度&#xff08;之前写过二…