Educational Codeforces Round 163 (Rated for Div. 2)(A,B,C,D,E)

比赛链接

好忙好忙好忙,慢慢补老比赛的题解了。

这场没啥算法,全是思维。有也是BFS,屎。


A. Special Characters

题意:

您将得到一个整数 n n n

您的任务是构建一串大写的拉丁字母。此字符串中必须正好有 n n n 个特殊字符。让我们称一个字符为特殊字符,如果它恰好等于它的一个邻居。

例如,AAABAACC字符串中有 6 6 6 个特殊字符(位置为: 1 1 1 3 3 3 5 5 5 6 6 6 7 7 7 8 8 8 )。

打印任何合适的字符串或报告没有这样的字符串。

思路:

发现如果是 AABBAABB 这样子的序列的话,每个字符都会是特殊字符。但是这样的只能构造出 n n n 为偶数时候的情况。考虑能否构造出 n n n 为奇数时候的情况。

因为一个字符为特殊字符只和它的左右相邻的字符有关,再往前是什么它是不在意的。所以我们构造 n n n 为奇数时候的情况时,前面的部分仍然用类似 AABB 这种形式来构造,因为三个及以上连续的字符挨在一起时,中间的字符就不是特殊字符,不会产生贡献了,只有两头的字符会产生贡献,它就和两个字符的等价,所以我们不妨规定挨在一起的相同字符最多有两个

于是,如果前面的部分结尾为 A A AA AA 时,我们后面会补上 B B B,这时这个 B B B 不是特殊字符,因此这时凑不出奇数情况。然后我们继续向后补字符,如果我们补 A A A,这个 A A A 也不是特殊字符,凑不出奇数情况,如果补 B B B,这时补的两个 B B B 都同时成为了特殊字符,相当于上面说的 A A B B AABB AABB 形式,仍然凑不出奇数情况。

如果我们在补上 B A BA BA,然后继续向后补字符,就会重复上面的讨论。因此无论怎么补,我们都凑不出奇数情况。这就意味着 n n n 为奇数时是无解的。

code:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=55;int T,n;
char s[maxn];int main(){cin>>T;while(T--){cin>>n;if(n&1){cout<<"NO"<<endl;continue;}else cout<<"YES"<<endl;for(int i=1;i<=n;i+=4)s[i]=s[i+1]='A';for(int i=3;i<=n;i+=4)s[i]=s[i+1]='B';for(int i=1;i<=n;i++)cout<<s[i];cout<<endl;}return 0;
}

B. Array Fix

题意:

您将得到一个长度为 n n n 的整数数组 a a a

您可以执行以下操作任意次数(可能为零):取数组 a a a 中至少为 10 10 10 的任何元素,将其删除,然后在相同位置插入该元素所包含的数字,按它们出现在该元素中的顺序。例如:

  • 如果我们将此操作应用于数组 [ 12 , 3 , 45 , 67 ] [12, 3, 45, 67] [12,3,45,67] 的第 3 3 3 个元素,则数组将变为 [ 12 , 3 , 4 , 5 , 67 ] [12, 3, 4, 5, 67] [12,3,4,5,67]

  • 如果我们将此操作应用于数组 [ 2 , 10 ] [2, 10] [2,10] 的第 2 2 2 个元素,则数组将变为 [ 2 , 1 , 0 ] [2, 1, 0] [2,1,0]

您的任务是确定是否可以使用上述操作任意次数使 a a a 按非降序排序。换句话说,您必须确定是否可以将数组 a a a 转换为 a 1 ≤ a 2 ≤ ⋯ ≤ a k a_1 \le a_2 \le \dots \le a_k a1a2ak ,其中 k k k 是数组 a a a 的当前长度。

思路:

先注意一下题目说了 0 ≤ a i ≤ 99 0 \le a_i \le 99 0ai99,因此 a i a_i ai 最多就是个两位数。

因为是非降序的,所以从某一位开始,也许后面就都变成了两位及以上的数,这时这些数不能被拆数位,否则变成一位数之后就会变小。反之,在此之前,所有的数都得是一位数,否则某个两位数后面出现了一位数,就不满足非降序的条件了。因此我们找到这个分界点,把分界点之前的所有数都拆掉,然后看满不满足条件就行了。

根据上面的分析,这个分界点之后的数都是不拆数位就满足非降序的,所以我们从后向前找到第一个不满足条件的位置,这个位置就是分界点了。从这个位置向前拆数。一个数拆开后,个位放在后面,十位放在前面。所以我们没必要真的把两个新的数插入到当前位置,这样比较麻烦。

判断这个数是否和后一个数满足非降序的关系,我们直接看一下当前数的十位不小于个位,并且个位不小于后一个数,之后用十位代替这个数,再向前找即可。

code:

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=55;int T,n,a[maxn];int main(){cin>>T;while(T--){cin>>n;for(int i=1;i<=n;i++)cin>>a[i];int idx;for(idx=n-1;idx>=1;idx--)if(a[idx]>a[idx+1])break;//		cout<<"***"<<idx<<endl;bool flag=true;for(int i=idx;i>=1;i--){if(a[i]/10>a[i]%10 || a[i]%10>a[i+1]){flag=false;break;}if(a[i]>10)a[i]/=10;}puts((flag)?"YES":"NO");}return 0;
}

C. Arrow Path

题意:

有一个网格,由 2 2 2 行和 n n n 列组成。这些行从上到下从 1 1 1 2 2 2 进行编号。列从左到右从 1 1 1 n n n 进行编号。网格的每个单元格都包含一个指向左侧或右侧的箭头。没有箭头指向网格外。

有一个机器人在单元格 ( 1 , 1 ) (1, 1) (1,1) 中启动 。每一秒钟,都有以下两个动作相继发生:

  1. 首先,机器人向左、向右、向下或向上移动(它不能尝试走出网格,也不能跳过这次移动

  2. 然后,它沿着放置在当前单元格(移动后结束的单元格)中的箭头移动。

您的任务是确定机器人是否可以到达单元 ( 2 , n ) (2, n) (2,n)

思路:

比较明显的BFS。

code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#define pii pair<int,int>
using namespace std;
const int maxn=2e5+5;int T,n;
string mp[5];int fx[]={1,-1,0,0},fy[]={0,0,1,-1};int main(){cin>>T;while(T--){cin>>n;cin>>mp[1]>>mp[2];mp[1]=" "+mp[1];mp[2]=" "+mp[2];queue<pii> q;vector<vector<bool> > vis(5,vector<bool>(n+5,false));q.push(pii(1,1));vis[1][1]=true;bool flag=false;while(!q.empty()){int ux=q.front().first,uy=q.front().second;q.pop();if(ux==2 && uy==n){flag=true;break;}for(int i=0,x,y;i<4;i++){x=ux+fx[i],y=uy+fy[i];if(x<1 || x>2 || y<1 || y>n)continue;if(mp[x][y]=='<')y--;else y++;if(!vis[x][y]){q.push(pii(x,y));vis[x][y]=true;}}}puts((flag)?"YES":"NO");}return 0;
}

D. Tandem Repeats?

题意:

您将得到一个字符串 s s s ,它由小写的拉丁字母以及问号组成。

串联重复序列(tandem repeat)是指长度为偶数的串,满足其前一半等于其后一半。

您的目标是将每个问号替换为某个小写拉丁字母,求出最大可能的串联重复序列子串的长度。

思路:

考虑到这个串联重复序列比如 a b c a b c abcabc abcabc,说白了就是第 1 1 1 个字符向后 3 3 3 个长度的子串与第 4 4 4 个字符向后 3 3 3 个长度的子串相同。那么一定第 2 2 2 个字符向后 2 2 2 个长度的子串与第 5 5 5 个字符向后 2 2 2 个长度的子串相同,前者可以由后者推出来。

所以我们设 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示从第 i i i 个字符开始的子串和第 j j j 个字符开始的子串最长匹配长度是多少。当第 i i i 个字符和第 j j j 个字符相同时(两个字符真的相同,或者其中一个为 ? ? ?,可以万能匹配), d p [ i ] [ j ] dp[i][j] dp[i][j] 就可以从 d p [ i + 1 ] [ j + 1 ] + 1 dp[i+1][j+1]+1 dp[i+1][j+1]+1 推过来。因为是从 i + 1 , j + 1 i+1,j+1 i+1,j+1 推来的,因此 i , j i,j i,j 的枚举需要反着,从 n n n 1 1 1

不过 i ∼ i + d p [ i ] [ j ] − 1 i\sim i+dp[i][j]-1 ii+dp[i][j]1 j ∼ j + d p [ i ] [ j ] − 1 j\sim j+dp[i][j]-1 jj+dp[i][j]1 两个区间的子串匹配不一定就是串联重复序列,它需要正好是 i + d p [ i ] [ j ] − 1 = j − 1 i+dp[i][j]-1=j-1 i+dp[i][j]1=j1 j − i = d p [ i ] [ j ] j-i=dp[i][j] ji=dp[i][j](也就是前后两个子串正好相接)。 d p [ i ] [ j ] dp[i][j] dp[i][j] 如果大于 j − i j-i ji,这时可以直接截取长为 j − i j-i ji 的一段作为串联重复序列,反之就一定无法成为串联重复序列。

code:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;int T,n;
string s;int main(){cin>>T;while(T--){cin>>s;n=s.length();s=" "+s;vector<vector<int> > dp(n+5,vector<int>(n+5,0));for(int i=n;i>=1;i--){for(int j=i-1;j>=1;j--){if(s[i]=='?' || s[j]=='?' || s[i]==s[j])dp[i][j]=dp[i+1][j+1]+1;}}int ans=0;for(int i=1;i<=n;i++){for(int j=1;j<i;j++){int t=dp[i][j];if(t>=i-j)t=i-j;else continue;ans=max(ans,t);}}cout<<ans*2<<endl;}return 0;
}

E. Clique Partition

题意:

给出两个整数 n n n k k k 。在 n n n 个顶点上有一个图,编号从 1 1 1 n n n ,它最初没有边。你必须给每个顶点分配一个整数,设 a i a_i ai 是顶点 i i i 上的整数。所有 a i a_i ai 都应该是从 1 1 1 n n n 的不同整数。

指定整数后,对于每对顶点 ( i , j ) (i, j) (i,j) ,如果 ∣ i − j ∣ + ∣ a i − a j ∣ ≤ k |i - j| + |a_i - a_j| \le k ij+aiajk ,则在它们之间添加一条边。

您的目标是创建一个图,该图可以划分为最小可能(对于给定的 n n n k k k 值)数量的团(Clique)。

图的每个顶点应该恰好属于一个团。

团是一组顶点,其中的每一对顶点都与一条边相连。由于布莱德斯特没有真正提高他的编程技能,他无法解决问题 “给一个图,将其划分为最小数量的团”。因此,我们要求您打印分区本身。

思路:

构造题,构造方法不好想。如果想出了构造方法,写是比较容易的。

要团的个数最少,那么就考虑让团包含的点最多。因为 a i a_i ai 互不重复,所以 ∣ a i − a j ∣ |a_i - a_j| aiaj 至少会是 1 1 1,那么 ∣ i − j ∣ |i - j| ij 最大就是 k − 1 k-1 k1,这时 j − i + 1 j-i+1 ji+1 最大就是 k k k。也就是说,团最多可能包含 k k k 个点

考虑如果一个团能否塞入 k k k 个点,不妨使用顶点 1 ∼ k 1\sim k 1k。而且为了不影响到其他团,所以我们尽量给它们分配 1 ∼ k 1\sim k 1k 的编号。

首先第 1 1 1 个数和第 k k k 个数必须差 1 1 1,否则这一对一定不满足条件。同理,第 1 1 1 个数和第 k − 1 k-1 k1 个数必须差 ≤ 2 \le 2 2,第 2 2 2 个数和第 k k k 个数必须差 ≤ 2 \le 2 2。考虑把第一个数置为中间数 k / 2 k/2 k/2,这样中间数两边都有空间,我们把中间数前面的数降序放在前半部分,中间数后面的数降序放在后半部分。即: k / 2 , k / 2 − 1 , … , 1 , k , k − 1 … , k / 2 + 2 , k / 2 + 1 k/2,k/2-1,\dots,1,k,k-1\dots,k/2+2,k/2+1 k/2,k/21,,1,k,k1,k/2+2,k/2+1

还是比较好验证这么构造的正确性的:前半部分一定满足条件,后半部分一定满足条件。前半部分取一个数,后半部分取一个数的情况也满足条件。综合一下,所有情况都满足条件。

这样 1 ∼ k 1\sim k 1k 的情况就构造出来了,因为相对位置和相对大小是不变的,所以后面的每个团也是这样构造就可以了。

有时候会剩下一些点不足 k k k 个。构造方式同理,把上面的序列截掉后面部分即可,大概就是这样:

  1. 如果 n ≤ k / 2 n\le k/2 nk/2,则 n , n − 1 , … , 1 n,n-1,\dots,1 n,n1,,1
  2. 如果 k / 2 < n < k k/2\lt n\lt k k/2<n<k,则 k / 2 , k / 2 − 1 , … , 1 , n , n − 1 … , k / 2 + 2 , k / 2 + 1 k/2,k/2-1,\dots,1,n,n-1\dots,k/2+2,k/2+1 k/2,k/21,,1,n,n1,k/2+2,k/2+1

团的个数也就很显然了,是 ⌈ n k ⌉ \left\lceil\dfrac nk\right\rceil kn。第 i i i 个点所属的团显然就是第 ⌈ i k ⌉ \left\lceil\dfrac ik\right\rceil ki 个团。

code:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=45;int T,n,k;
int a[maxn];int main(){cin>>T;while(T--){cin>>n>>k;for(int i=1,len=k;i<=n;i+=k){if(i+k-1<=n){for(int j=i;j<i+len;j++)a[j]=j;reverse(a+i,a+i+len/2);reverse(a+i+len/2,a+i+len);}else {if(i+len/2>=n){for(int j=i;j<=n;j++)a[j]=j;reverse(a+i,a+n+1);}else {for(int j=i;j<=n;j++)a[j]=j;reverse(a+i,a+i+len/2);reverse(a+i+len/2,a+n+1);}}}
//		cout<<"***";for(int i=1;i<=n;i++)printf("%d ",a[i]);puts("");cout<<(n+k-1)/k<<endl;for(int i=1;i<=n;i++){printf("%d ",(i+k-1)/k);}puts("");}return 0;
} 

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

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

相关文章

Docker - 哲学 默认网络和 自定义网络 与 linux 网络类型 和 overlay2

默认网络&#xff1a;不指定 --nerwork 不指定 网络 run 一个容器时&#xff0c;会直接使用默认的网络桥接器 &#xff08;docker0&#xff09; 自定义网络&#xff1a;指定 --nerwork 让这两台容器互相通信 的前提 - 共享同一个网络 关于 ip addr 显示 ens160 储存驱动 ov…

入门linux之Ubuntu学习

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1、介绍Ubuntu2、虚拟机目录解析3、常用指令ls&#xff1a;罗列当前目录文件信息对ls -l 的结果解析1.第一个字符2.每三个字符&#xff08;第一个字符后&#x…

jmeter超高并发报错解决方法

1、比如jmeter设置并发量为5000&#xff0c;运行后报错socket closed。原因是客户端与服务端做了三次握手之后&#xff0c;后面不需要握手了&#xff0c;但是jmeter没有这个功能&#xff0c;5000个并发每次发接口请求都是独立的&#xff0c;jmeter端口处理不了这么大量的请求&a…

【嵌入式DIY实例】-DIY 灌水机

DIY 灌水机 文章目录 DIY 灌水机1、硬件准备2、YF-S201 霍尔效应水流量传感器介绍3、4x4矩阵键盘4、硬件接线5、代码实现在这个项目中,我们将使用流量传感器和 Arduino 构建一个水灌装机。用户使用 44 键盘输入液体总量。泵在收到用户输入后抽取准确数量的水。当准确数量完成后…

v-for=“item in arr“ 的理解

在 Vue.js 中&#xff0c;v-for 是一个指令&#xff0c;用于在模板中渲染一个列表的数据。v-for"item in arr" 这个语法中&#xff0c;item 和 arr 分别代表以下含义&#xff1a; item: item 是当前迭代到的数组元素或对象的别名。在每次迭代中&#xff0c;item 会被…

Android视角看鸿蒙第八课(module.json5中的各字段含义之abilities)下

Android视角看鸿蒙第八课(module.json5中的各字段含义之abilities&#xff09;下 导读 上篇文章开始学习abilities下的各字段含义&#xff0c;因为篇幅原因只学习了name、srcEntry、description、icon和label字段的含义和用法&#xff0c; 这篇文章继续学习和了解其他字段。 …

GPT4.0

GPT4.0 支持官网所有功能以及所有第三方GPTS&#xff0c;完全同步官网。无需魔法&#xff0c;填写授权码直达官网。全天超18小时维护&#xff0c;无需担心不稳定。没有永久卡&#xff0c;3.5免费提供&#xff0c;4.0可以按需下单即可&#xff0c;不存在跑路。 需要的联系

格瑞纳电子邀您参观2024杭州快递物流展

2024长三角快递物流供应链与技术装备展览会 2024.7.8-10 杭州国际博览中心 参展企业介绍 北京格瑞纳电子产品有限公司是一家立足于专业科学技术领域集产品代理、培训咨询和个性化增值服务的高科技公司&#xff0c;于2009年成立于北京&#xff0c;立足于复杂系统仿真领域&…

皓学IT:WEB06_ EL表达式JSTL标签库

一、EL表达式 1.1.特点 是一个由java开发的工具包 用于从特定域对象中读取并写入到响应体开发任务&#xff0c;不能向域对象中写入。 EL工具包自动存在Tomcat的lib中&#xff08;el-api.jar&#xff09;&#xff0c;开发是可以直接使用&#xff0c;无需其他额外的包。 标准…

seleniumUI自动化实例(登录CSDN页面)

今天分享一个CSDN登录模块的登录场景 1.配置文件 CSDNconf.py&#xff1a; from selenium import webdriver options webdriver.ChromeOptions() options.binary_location r"D:\Program Files\360\360se6\Application\360se.exe" # 360浏览器安装地址 driver w…

电脑审计系统知多少

域智盾的电脑审计系统是一款功能强大的软件&#xff0c;主要用于监控和审计电脑的使用情况。通过安装该系统&#xff0c;组织能够全面了解员工的电脑活动。 首先&#xff0c;该系统能够详细记录用户的上网记录&#xff0c;包括访问的网站、浏览的网页内容等。这使得管理员可以监…

剑指offer面试题42 翻转字符顺序 VS 左旋字符串

考察点 字符串遍历知识点 题目 分析 类似这种题目只能观察元素特点找出规律确定算法了&#xff0c;像第一道题目翻转单词顺序&#xff0c;我们可以很容易的得到翻转每个字符后的的字符串&#xff0c;再仔细观察一下紧接着以空格为间隔分别翻转俩边的字符串就可以解这道题目了…

鸿蒙Harmony应用开发—ArkTS-@Provide装饰器和@Consume装饰器:与后代组件双向同步

Provide和Consume&#xff0c;应用于与后代组件的双向数据同步&#xff0c;应用于状态数据在多个层级之间传递的场景。不同于上文提到的父子组件之间通过命名参数机制传递&#xff0c;Provide和Consume摆脱参数传递机制的束缚&#xff0c;实现跨层级传递。 其中Provide装饰的变…

YOLOv8 如何实现多主干特征融合方式 | GhostNet+ShuffleNet / SwinTransformer+ShuffleNet

文章目录 前言模块添加方法双特征提取例子`GhostNet+ShuffleNet` 双主干结构图代码`Swin+ShuffleNet` 双主干结构图代码参数量与计算量1. 什么是YOLO-Magic框架?2. 如何加入这个框架?3. 加入后如何使用框架?4. GitHub组织是什么?

LeetCode-热题100:39.组合总和

题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被…

使用 Python 读取 Word 文件

使用 Python 读取 Word 文件 0. 引言安装必要的库 1. 读取和提取 Word 文件中的文本2. 提取 Word 文件中的图片 0. 引言 要使用 Python 读取 Word 文件并识别其中的对象&#xff08;如图片&#xff09;和文本&#xff0c;你可以使用 python-docx 库来处理文本&#xff0c;和 d…

大数定律与中心极限定理

大数定律与中心极限定理 大数定律切比雪夫不等式依概率收敛切比雪夫大数定律辛钦大数定律伯努利大数定律 中心极限定理列维-林德伯格中心极限定理&#xff08;Lindeberg-Levy central limit theorem&#xff09;棣莫弗-拉普拉斯中心极限定理&#xff08;De Moivre-Laplace cent…

【运放】LM358和LM324

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…

python脚本for循环

使用python脚本单个输出Hello单词。 for循环实例&#xff1a; ​ [rootkvm-72 py]# cat for02.py #for i in hello: #for i in "hello": #for i in hello: for i in """hello""":print("i ", i)​ 单个字符输出结果&…

C语言运算符优先级

C语言运算符的优先级&#xff08;从高到低&#xff09;如下所示&#xff1a; 1. ()&#xff1a;括号 2. []&#xff1a;数组索引 3. . 和 ->&#xff1a;结构体和联合体成员选择 4. 和 --&#xff1a;自增和自减 5. !&#xff1a;逻辑非 6. ~&#xff1a;位取反 7. -&…