Codeforces 923 div3 A-G

A

题目分析:

记录隔得最远的两个'B'的距离

C++代码:

#include<iostream>
using namespace std;
int main(){int t;cin>>t;while(t--){int n;cin>>n;string s;cin>>s;int a=0,b=0,cnt=0;//a:第一个B的下标  b:最后一个B的下标for(int i=0;i<s.size();i++)if(s[i]=='B'){cnt++;if(cnt==1)a=i;b=max(b,i);}cout<<b-a+1<<endl;}return 0;
}

B

题目分析:

从前往后填,每次枚举26个英文字母的使用次数,与a[i]相等就用该字母,用完次数记得加一

C++代码:

#include<iostream>
using namespace std;
const int N=200010;
int a[N];
int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t;cin>>t;while(t--){int n,cnt[26]={0};cin>>n;string s;for(int i=0;i<n;i++)cin>>a[i];for(int i=0;i<n;i++){for(int j=0;j<26;j++)if(cnt[j]==a[i]){//如果字母在此之前使用的次数为a[i]次,则用该字母s+=(char)(j+'a');cnt[j]++;//该字母的使用次数加一break;}}cout<<s<<endl;}return 0;
}

C

题目分析:

找到所有1~k的元素中

第一个数组中出现的元素个数sum1(去重后)

第二个数组中出现的元素个数sum2(去重后)

二者的公共元素sum3(去重后)

sum1-=sum,sum2-=sum,此时sum1和sum2就是两个数组独有的元素个数

1、sum1+sum+sum2<k    一定找不到可行方案

2、sum1+sum+sum2==k 

        如果sum1<=k/2&&sum2<=k/2则表示一定可以找到方案

        否则找不到

C++代码:

#include<iostream>
using namespace std;
const int N=400010;
int main(){int t;cin>>t;while(t--){int n,m,k,sum=0,sum1=0,sum2=0;//sum记录两个数组的公共元素(1~k中),sum1(sum2)记录第一(二)个数组中的元素个数(1~k中)cin>>n>>m>>k;int cnt1[N]={0},cnt2[N]={0};//记录两个数组中数出现的个数,方便判重 for(int i=0;i<n;i++){int x;cin>>x;if(x>=1&&x<=k){cnt1[x]++;if(cnt1[x]==1)sum1++;}}for(int i=0;i<m;i++){int x;cin>>x;if(x>=1&&x<=k){cnt2[x]++;if(cnt2[x]==1){if(cnt1[x])sum++;sum2++;}}}//sum1和sum2都减去公共元素sum1-=sum,sum2-=sum;//如果总元素个数不等于k,直接输出Noif(sum1+sum+sum2<k)puts("No");else{//否则一定等于kif(sum1<=k/2&&sum2<=k/2)puts("Yes");else puts("No");}}return 0;
}

 D

题目分析:

用一个数组last[]记录每个元素前面与它最近的不相同的元素下标,从前往后更新last即可

C++代码:

#include<iostream>
#include<cstring>
using namespace std;
const int N=200010;
int a[N],last[N];
int n,q;
int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t;cin>>t;while(t--){cin>>n;//last[i]记录上一个与a[i]不同的元素的下标memset(last,-1,sizeof last);for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++){if(a[i-1]!=a[i])last[i]=i-1;else last[i]=last[i-1];}cin>>q;while(q--){int l,r;cin>>l>>r;//如果与a[r]不同的上一个元素的下标小于l,则一定无解if(last[r]<l)cout<<-1<<" "<<-1<<endl;else cout<<last[r]<<" "<<r<<endl;//否则直接输出}}return 0;
}

 E

题目分析:

max(s)-min(s)<=1

由于是排列,所以任意相邻的两个长度为k的子数组的和一定不同,所以需要构造成

s[i]-s[i-1]=1,s[i+1]-s[i]=-1...这样,才可以保证max(s)-min(s)<=1

举个例子:n=9,k=3

假设前三个元素为[x,y,z],由于s[2]-s[1]=第四个元素-x=1,所以第四个元素为x+1,同理构造如下:

[x,y,z,x+1,y-1,z+1,x+2,y-2,z+2]

所以把9分成[1,2,3]、[4,5,6]、[7,8,9]三块,奇数块从小到大输出,偶数块从大到小输出,所以

序列为1,6,7,2,5,8,3,4,9,由此可见,每个块中的元素每隔k次出现一次

1、n%k==0的情况,只需要分成k个块,按如上操作即可

2、n%k!=0,其实还是分成k个块,只是可能每个块中数的个数可能不一样

在代码中,我们并不会把分块的过程写出来,而是让第一个奇数块从l=1开始放,第一个偶数块从r=n开始放,每个奇数块放完就 l++,每个偶数块放完就 r--,然后下一个奇数块又从l开始放,偶数块又从r开始放,直到放满n个数

(看不太明白可以看代码模拟一下hh)

C++代码:

#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int N=2e5+10;
int a[N];
void solve(){int n,k;cin>>n>>k;vector<int> ans(n+1);int l=1,r=n;for(int i=1;i<=k;i++){if(i&1){//奇数块从小到大输出for(int j=i;j<=n;j+=k){//每隔k个数放一个该块中的数ans[j]=l;l++;}}else{//偶数块从大到小输出for(int j=i;j<=n;j+=k){//每隔k个数放一个该块中的数ans[j]=r;r--;}}}for(int i=1;i<=n;i++)cout<<ans[i]<<" ";cout<<endl;
}int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int t;cin>>t;while(t--){solve();}return 0;
}

 F

题意分析:

一开始看到这题感觉是tarjan(学tarjan学魔怔了hh)

然后发现并查集好像可以做,要求所有环内的最小边,故先将所有边存起来,然后从大到小排序

枚举每条边,如果两个端点不在一个连通块,则让这两个端点合并,否则加上这条边一定会形成环,就不加上该边,设置一个变量 t 存储每个环的最小边的编号

为什么是一个变量存储每个环 ?

因为我们是从大到小枚举每条边,每次枚举到一个环的时候,当前环的最小边一定比之前小,所以直接更新 t 即可

找到 t 后,用bfs搜出环内的所有点存起来然后输出即可

C++代码:

#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int N=200010;
int a[N],p[N];
bool st[N];
int pre[N];
int n,m;
struct Node{int u,v,w;
}e[N];//存储所有的边 
vector<int> g[N];
int find(int x){//并查集求祖宗节点+路径压缩if(p[x]!=x)p[x]=find(p[x]);return p[x];
}
bool merge(int a,int b){int pa=find(a),pb=find(b);//如果a,b本来就在一个连通块,则表明加上这条边一定会形成环,返回false if(pa==pb)return false;//合并成功并返回true p[pa]=pb;return true;
}
bool cmp(Node a,Node b){//排序用return a.w>b.w;
}
void solve(){cin>>n>>m;for(int i=1;i<=n;i++)p[i]=i,g[i].clear();for(int i=1;i<=m;i++){int u,v,w;cin>>u>>v>>w;e[i]={u,v,w};g[u].push_back(v),g[v].push_back(u);}sort(e+1,e+m+1,cmp);//将所有边从大到小排序 int t=0;//记录简单循环的最小边的编号 for(int i=1;i<=m;i++)if(!merge(e[i].u,e[i].v))//如果会成环,则不合并这两个点,且更新t t=i;int u=e[t].u,v=e[t].v;//记录权重最小的简单循环中的两个点的编号 memset(st,false,sizeof st);//宽搜出所有环内的点queue<int> q;q.push(u);st[u]=true;while(!q.empty()){int a=q.front();q.pop();for(int i=0;i<g[a].size();i++){//枚举a的所有的邻点 int b=g[a][i];if(a==u&&b==v)continue;if(st[b])continue;st[b]=true;pre[b]=a;//b是从a过来的 q.push(b);}}int cur=v;//先记录终点 vector<int> ans;while(cur!=u){ans.push_back(cur);//记录答案 cur=pre[cur];//往回搜 }ans.push_back(u);//不要忘记把起点加入到ans cout<<e[t].w<<" "<<(int)ans.size()<<endl;//输出最小边的权值和该简单循环中含有的点数 //输出答案 for(int i=0;i<ans.size();i++)cout<<ans[i]<<" ";cout<<endl;
}
int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t;cin>>t;while(t--){solve();}return 0;
}

G

题意分析:

动态规划

这题的状态定义就很逆天,根本不是我这种蒟蒻能想到的 T^T

f[i][j][k]

1、状态表示:

      集合:当前使用第i个元素,最左侧未被染色的位置是j,最右侧被染色的位置是k的所有                     方案(即1~j-1全都被染色了,k+1~n没被染色,中间随意)

      属性:Min(最小操作数)

2、状态计算:

      a. 第i个元素不做任何操作  f[i][j][k]=f[i-1][j][k]

      b. 向左染色   l=max(1,i-a[i]+1),染 [l,i] 这个区间

          l>j时,此时最左边未被染色的位置还是j

          ①k>=i,最左边未被染色的位置还是j,最右侧被染色的位置还是k,忽略当前情况,不                 用操作

          ②k<i,若染色,则f[i][j][max(i,k)]=min(f[i][j][max(i,k)],f[i-1][j][k]+1),但是此时[j,l-1]还                   是有一部分未被染色的。由于我们最终要染完所有的位置,当前我们已经用到了第i               个数,所以后面[i+1,n]中一定有一个位置向前染色会覆盖 j ,故此时染[l,i]的区间并不                 是最优的,当前情况也可忽略,不用操作

          l<=j时

          ①k>i,最左边未被染色的位置是 k+1,最右边被染色的位置是k

              为什么呢?因为k一定是i-1及其之前的位置向右染色染到了k,所以包含了i,此时就                [1,k]都被染色了。所以转移方程为:

              f[i][k+1][k]=min(f[i][k+1][k],f[i-1][j][k]+1)

          ②k<=i,最左边未被染色的位置是i+1,最右边被染色的位置是 i 

              f[i][i+1][i]=min(f[i][i+1][i],f[i-1][j][k]+1)

          int t=max(i,k)

          状态转移方程:f[i][t+1][t]=min(f[i][t+1][t],f[i-1][j][k]+1)

      c. 向右染色   r=min(i+a[i]-1,n),染 [i,r] 这个区间

          ①j<i,最左边未被染色的位置还是 j,最右边染色的位置是max(r,k)

          转移方程:f[i][j][max(k,r)]=min(f[i][j][max(k,r)],f[i-1][j][k]+1)

          这种情况跟b中②同样都会有后一个向前染色覆盖 j,但是这种情况不一定会覆盖 i 向             右染色的区间,所以这种情况是有意义的,要加上

          ②j>=i ,最左边未被染色的位置是max(r,k)+1,最右边染色的位置是max(r,k)

          int t=max(i,k)

          状态转移方程:f[i][t+1][t]=min(f[i][t+1][t],f[i-1][j][k]+1)

          

include<iostream>
using namespace std;
const int N=110,INF=0x3f3f3f3f;
int a[N];
int f[N][N][N];
int n;
void solve(){cin>>n;for(int i=1;i<=n;i++)cin>>a[i];for(int i=0;i<=n;i++)for(int j=1;j<=n+1;j++)for(int k=0;k<=n;k++)f[i][j][k]=INF;f[0][1][0]=0;for(int i=1;i<=n;i++){for(int j=1;j<=n+1;j++){for(int k=0;k<=n;k++){f[i][j][k]=min(f[i][j][k],f[i-1][j][k]);int l=max(i-a[i]+1,1);if(l<=j){int t=max(i, k);f[i][t+1][t]=min(f[i][t+1][t],f[i-1][j][k]+1);}int r=min(i+a[i]-1,n);if(j<i){f[i][j][max(k,r)]=min(f[i][j][max(k,r)],f[i-1][j][k]+1);}else{int t=max(k, r);f[i][t+1][t]=min(f[i][t+1][t],f[i-1][j][k]+1);}}}}cout<<f[n][n+1][n]<<endl;
}
int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t;cin>>t;while(t--){solve();}return 0;
}

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

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

相关文章

python gradio 的输出展示组件

HTML&#xff1a;展示HTML内容&#xff0c;适用于富文本或网页布局。JSON&#xff1a;以JSON格式展示数据&#xff0c;便于查看结构化数据。KeyValues&#xff1a;以键值对形式展示数据。Label&#xff1a;展示文本标签&#xff0c;适用于简单的文本输出。Markdown&#xff1a;…

JavaScript之WebAPIs-BOM

目录 BOM操作浏览器一、Window对象1.1 BOM&#xff08;浏览器对象模型&#xff09;1.2 定时器-延时函数1.3 js执行机制1.4 location对象1.5 navigator对象1.6 history对象 二、本地存储三、补充数组中的map方法数组中的join方法数组中的forEach方法(重点)数组中的filter方法(重…

Linux——Centos系统安装(动图演示)

一、创建虚拟机并做相应配置 打开VMware Workstation&#xff0c;选择创建新的虚拟机&#xff1b; 1、选择自定义选项&#xff1a;点击下一步 2、选择虚拟机硬件兼容性&#xff1a;直接下一步就行了&#xff1b;点击下一步 3、安装客户机操作系统&#xff1a;这里我们选择稍后安…

C++对象模型之绕过private权限修饰符

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、C对象模型二、演示1.类层次2.内存排列 总结 前言 咱们都知道C语言在创建类的时候data member&#xff08;数据成员&#xff09;和fuchtion member&#xf…

C++文件操作-二进制文件-写文件

#include<iostream>//1、包含头文件 fstream #include<fstream> using namespace std;class Person { public:char m_Name[64];//姓名int m_Age;//年龄 };void test01() {//2、创建流对象ofstream ofs;//3、打开文件ofs.open("person.txt", ios::out | i…

Linux操作系统的有关常用的命令

1.linux系统的概述 1.1 什么是Linux系统? Linux&#xff0c;全称GNU/Linux&#xff0c;是一种免费使用和自由传播的类UNIX操作系统&#xff0c;其内核由林纳斯本纳第克特托瓦 兹&#xff08;Linus Benedict Torvalds&#xff09;于1991年10月5日首次发布&#xff0c;它主要受…

Mysql集合转多行

mysql 集合转多行 SELECT substring_index(substring_index(t1.group_ids, ,, n), ,, -1) AS group_id FROM (select 908,909 as group_ids ) t1, (SELECT rownum : rownum 1 AS n FROM ( SELECT rownum : 0 ) r, orders ) t2 WHERE n < ( LENGTH( t1.group_ids ) - LENGT…

【Linux】微基准测试

1、基准测试和微基准测试 1.1 定义 1)基准测试(Benchmark Testing): 基准测试是一种用于衡量计算机系统、软件应用或硬件组件性能的测试方法。它通过运行一系列标准化的任务场景来测量系统的性能表现,旨在帮助评估系统的各种指标,如响应时间、吞吐量、延迟、资源利用率…

LVGL项目实战之UI规划

LVGL项目实战之UI规划 ** 实物购买&#xff1a;TB 南山府嵌入式 ** 我们在在做项目之前&#xff0c;先需要确定项目的需求以及可能实现的功能&#xff0c;我们只有确定这些才能够对整体的框架进行把握。 本小结就说一下我们这个项目的一个整体的框架结构以及功能。 1-硬件构…

C++基础知识:C++中的引用,引用的函数的参数,值传递和址传递和引用传递的区别,以及代码演示。

1.值传递(实参值不变) #include<iostream>using namespace std;//1.值传递(实参值不变) void Swap01(int a,int b){int tempa;ab;btemp;cout<<"形式参数a"<<a<<endl;cout<<"形式参数b"<<b<<endl; }int main(){…

C语言实现二叉树以及二叉树的详细介绍

目录 1.树概念及结构 1.1树的概念 1.2树的相关概念 1.3树的表示 2.二叉树概念及结构 2.1二叉树的概念 2.2特殊的二叉树 2.3二叉树的性质 2.4二叉树的存储结构 3.二叉树顺序结构--特殊的二叉树--堆及其实现 3.1堆的概念及结构 3.2堆的实现 3.2.1堆的结构 3.2.2堆…

快速排序算法详解

快速排序&#xff08;Quick Sort&#xff09;是计算机科学与技术领域中非常经典的一种排序算法&#xff0c;由C. A. R. Hoare在1960年提出。它应用分治思想进行排序&#xff0c;通过对数据进行分区操作&#xff0c;并递归地对分区后的子序列进行排序&#xff0c;从而达到整个序…

骑砍战团MOD开发(52)-使用BrfExporterBlender制作BRF文件

一.Blender模型导出为BRF文件 import bpy import structclass BrfFile:def __init__(self):self.meshes []self.bodies []class Mesh:def __init__(self):self.name self.material_name self.vertices []self.morph_keys []self.vertices_fvf []self.faces []class Ve…

《JavaSE》---21.<简单认识Java的集合框架包装类泛型>

目录 前言 一、什么是集合框架 1.1类和接口总览 二、集合框架的重要性 2.1 开发中的使用 2.2 笔试及面试题 三、背后所涉及的数据结构 3.1 什么是数据结构 3.2 容器背后对应的数据结构 四、包装类 4.1 基本数据类型和对应的包装类 4.2 装箱和拆箱 1.最初的写法 2.…

org.springframework.context.ApplicationContext发送消息

1、创建消息的实体类 package com.demo;/*** 监听的实体类**/ public class EventMessage {private String name;public EventMessage(String name) {this.name name;}public String getName() {return name;}public void setName(String name) {this.name name;} }2、创建消…

【Linux】如何使用docker快速部署Stirling-PDF并实现远程处理本地文档

文章目录 前言1. 安装Docker2. 本地安装部署StirlingPDF3. Stirling-PDF功能介绍4. 安装cpolar内网穿透5. 固定Stirling-PDF公网地址 前言 本篇文章我们将在Linux上使用Docker在本地部署一个开源的PDF工具——Stirling PDF&#xff0c;并且结合cpolar的内网穿透实现公网随时随…

lua 实现 函数 判断两个时间戳是否在同一天

函数用于判断两个时间戳是否在同一天。下面是对代码的详细解释&#xff1a; ### 函数参数 - stampA 和 stampB&#xff1a;两个时间戳&#xff0c;用于比较。- resetInfo&#xff1a;一个可选参数&#xff0c;包含小时、分钟和秒数&#xff0c;用于调整时间戳。 ### 函数实现…

Java 集合框架:Java 中的双端队列 ArrayDeque 的实现

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 019 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…

共享模型之无锁

一、问题提出 1.1 需求描述 有如下的需求&#xff0c;需要保证 account.withdraw() 取款方法的线程安全&#xff0c;代码如下&#xff1a; interface Account {// 获取余额Integer getBalance();// 取款void withdraw(Integer amount);/*** 方法内会启动 1000 个线程&#xf…

[技术总结] C++ 使用经验

const 和 constexpr 有什么区别. const 一般是设置一个只读的属性, 在运行时还有可能通过cast变成一个可修改的. 但是constexpr是告诉编译器这就是一个常亮, 在编译时就可以计算出来然后进行替换.static 修饰的成员函数 & 成员变量 static 修饰的成员函数只能访问 static 修…