A - 22222

遍历字符串\(s\),按题意输出所有2即可。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
string s;
signed main(){
cin>>s;
for(auto a:s) if(a=='2') cout<<a;
return 0;
}

B - cat

按题意模拟即可。

点击查看代码
#include<bits/stdc++.h>
#define N 60
using namespace std;
int n;
string s[N];
signed main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>s[i];
sort(s+1,s+1+n,[](string a,string b){
return a.size()<b.size();
});
for(int i=1;i<=n;i++) cout<<s[i];
return 0;
}

C - Debug

容易发现答案就是将原字符串所有形如WWW...WWWA的子串替换成ACCC...CCC,如此模拟即可得到答案。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
string s;
int n;
signed main(){
cin>>s;
n=s.size();
int pos=-1;
for(int i=0;i<n;i++){
if(s[i]=='W'){
if(pos==-1) pos=i;
}else if(s[i]=='A'){
if(~pos){
cout<<"A";
for(int j=pos;j<i;j++) cout<<"C";
pos=-1;
}else{
cout<<"A";
}
}else{
if(~pos){
for(int j=pos;j<i;j++) cout<<s[j];
pos=-1;
}
cout<<s[i];
}
}
if(~pos){
for(int j=pos;j<n;j++) cout<<s[j];
pos=-1;
}
return 0;
}

上面是赛时思路,稍有点繁琐。实际上不难发现,我们可以直接倒序遍历字符串,遇到WA便修改成AC

这样做是正确的,因为每次修改只可能对之前的字符串产生影响。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
string s;
int n;
signed main(){
cin>>s,n=s.size();
for(int i=n-1;i>0;i--){
if(s[i]=='A'&&s[i-1]=='W'){
s[i]='C',s[i-1]='A';
}
}
cout<<s;
return 0;
}

D - Colorful Bracket Sequence

居然是括号匹配模板题w

具体过程如下,类似于模拟,所以正确性比较显然:

定义一个栈,初始为空。

对于\(i=1,2,\dots,n\),依次遍历\(s_i\):

  • 如果\(s_i\)是左括号,将\(s_i\)入栈。
  • 如果\(s_i\)是右括号,取出栈顶的左括号,看是否与\(s_i\)匹配。如果不匹配或者栈为空,断定No

如果最终栈非空,断定No,否则断定Yes

点击查看代码
#include<bits/stdc++.h>
using namespace std;
stack<char> st;
string s;
bool solve(){
for(char i:s){
if(i=='('||i=='['||i=='<'){
st.push(i);
}else{
if(st.empty()) return 0;
char c=st.top();
st.pop();
if(i==')'&&c!='(') return 0;
if(i==']'&&c!='[') return 0;
if(i=='>'&&c!='<') return 0;
}
}
return st.empty();
}
signed main(){
cin>>s;
cout<<(solve()?"Yes":"No");
return 0;
}

E - Palindromic Shortest Path

考虑到一个回文串的头尾各添加一个相同的字符,仍然是一个回文串,所以考虑使用BFS求解,队列里存的是形如\((u,v)\)的路径。

  • 先对于\(i=1,2,\dots,n\),将长度为\(0\)的路径\((i,i)\)加入队列,并令\(ans_{i,i}=0\)。

  • 再对于\((u,v)\in E\),将长度为\(1\)的路径\((u,v)\)加入队列,并令\(ans_{u,v}=1\)。

  • 接下来进行BFS,对于从队头取出的\((x,y)\)这条路径,枚举\(1\le i,j\le n\),若同时满足:

    • \(ans_{i,j}\)未被更新。
    • \((i,x),(y,j)\in E\)。
    • \((i,x),(y,j)\)

    则令\(ans_{i,j}=ans_{x,y}+1\),并将\((i,j)\)入队。

由于我们保证队列中每个路径的\(ans\)从队头到队尾不降,所以\(ans_{i,j}\)第一次更新的值一定是最小的。自然正确性可以保证。

时间复杂度:最多\(O(n^2)\)次入队操作,枚举\(i,j\)是\(O(n^2)\)的。所以时间复杂度是\(O(n^4)\)。

点击查看代码
#include<bits/stdc++.h>
#define N 105
using namespace std;
int n,ans[N][N];
string a[N];
queue<pair<int,int>> q;
signed main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],a[i]=' '+a[i];
memset(ans,-1,sizeof ans);
for(int i=1;i<=n;i++) ans[i][i]=0,q.push({i,i});
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
if(i!=j&&a[i][j]!='-') ans[i][j]=1,q.push({i,j});
while(!q.empty()){
auto [x,y]=q.front();//注意 该写法仅c++17或以上可用
q.pop();
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
if(ans[i][j]==-1&&a[i][x]==a[y][j]&&a[i][x]!='-')
ans[i][j]=ans[x][y]+2,q.push({i,j});
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) cout<<ans[i][j]<<" ";
cout<<"\n";
}
return 0;
}

\(O(n^4)\)居然是正解,难道哪里跑不满吗……?

也存在\(O(n^3+26n^2)\)的做法,at上有题解,改天补。

F - Alkane

考虑树形dp。

由于一个烷烃只包含度为\(1,4\)的节点,当我们规定必须从子树\(u\)中选定一个包含\(u\)的连通块作为烷烃时,根据\(u\)的度数,可能的形态只有下面两种:

所以我们考虑计算一个\(f\)数组,其中\(f_u\)表示从子树\(u\)中选定一个包含\(u\)的最大连通块,使得它是一个严格三叉树(非叶节点都有\(3\)个子节点)时,该连通块的大小。

\(f_u\)的计算过程如下,其中\(ch\)表示\(u\)的子节点个数:

  • 若\(ch<3\),\(f_u=1\)。
  • 若\(ch\ge 3\),\(f_u=f_{i_1}+f_{i_2}+f_{i_3}+1\)。其中\(i_x\)表示\(u\)的子节点中,\(f\)值第\(x\)大的节点。

然后就是计算答案了,讨论上图中\(2\)种情况。对于节点\(u\):

  • 若\(ch\ge 4\),有\(f_{i_1}+f_{i_2}+f_{i_3}+f_{i_4}+1\)的贡献,\(i\)的含义同上。
  • 若\(ch\ge 3\),且\(u\)不是根节点,有\(f_{i_1}+f_{i_2}+f_{i_3}+2\)的贡献。

时间复杂度为\(O(n)\)。

代码将计算\(f\)和计算答案这\(2\)个步骤合在一起写了。

点击查看代码
#include<bits/stdc++.h>
#define N 200010
using namespace std;
int n,ans;
vector<int> G[N];
int dfs(int u,int fa){
int maxx[4]={0},ch=0;
for(int i:G[u]){
if(i==fa) continue;
int t=dfs(i,u);
ch++;
if(t>=maxx[0]) maxx[3]=maxx[2],maxx[2]=maxx[1],maxx[1]=maxx[0],maxx[0]=t;
else if(t>=maxx[1]) maxx[3]=maxx[2],maxx[2]=maxx[1],maxx[1]=t;
else if(t>=maxx[2]) maxx[3]=maxx[2],maxx[2]=t;
else if(t>=maxx[3]) maxx[3]=t;
}
if(ch<=2) return 1;
if(ch>=4) ans=max(ans,maxx[0]+maxx[1]+maxx[2]+maxx[3]+1);
if(u!=1) ans=max(ans,maxx[0]+maxx[1]+maxx[2]+2);
return maxx[0]+maxx[1]+maxx[2]+1;
}
signed main(){
cin>>n;
for(int i=1,u,v;i<n;i++){
cin>>u>>v;
G[u].emplace_back(v);
G[v].emplace_back(u);
}
dfs(1,0);
cout<<(ans?ans:-1)<<"\n";
return 0;
}

G - Dense Buildings

发现答案的限制因素是始末两点间路径上,最矮的建筑。

为了使答案最优,我们要最大化这个建筑高度,所以这是一个最大瓶颈路问题。

我们根据输入建图,两点间的权值为它们高度的最小值。

然后跑原图的最大生成树,用LCA维护两点间的最小值,即为我们要最大化的建筑高度。

对于每个询问,设这个高度为\(h\),那么如果\(h\ge y\)或\(h\ge z\),则输出\(|y-z|\),否则输出\(y+z-2h\)。

注意特判始末位置相同的情况,输出\(|y-z|\)。

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define H 505
#define W 505
#define N (H*W)
#define M (N<<2)
#define eb emplace_back
using namespace std;
struct edge{int to,w;};
struct _edge{int u,v,w;}e[M];
int n,m,q,l[H][W],idx,fa[N],f[N][20],minn[N][20],dep[N];
vector<edge> G[N];
void add(int u,int v,int w){G[u].eb(edge{v,w}),G[v].eb(edge{u,w});}
void eadd(int u,int v,int w){e[++idx]={u,v,w};}
int getid(int x,int y){return (x-1)*m+y;}
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void dfs(int u){
dep[u]=dep[f[u][0]]+1;
for(int i=1;i<20;i++){
f[u][i]=f[f[u][i-1]][i-1];
minn[u][i]=min(minn[u][i-1],minn[f[u][i-1]][i-1]);
}
for(edge i:G[u]){
int v=i.to,w=i.w;
if(v==f[u][0]) continue;
f[v][0]=u,minn[v][0]=w,dfs(v);
}
}
int getmin(int u,int v){
int ans=LLONG_MAX;
if(dep[u]>dep[v]) swap(u,v);
for(int i=19;~i;i--) if(dep[f[v][i]]>=dep[u]) ans=min(ans,minn[v][i]),v=f[v][i];
if(u==v) return ans;
for(int i=19;~i;i--) if(f[v][i]!=f[u][i]) ans=min({ans,minn[u][i],minn[v][i]}),u=f[u][i],v=f[v][i];
return min({ans,minn[u][0],minn[v][0]});
}
signed main(){
memset(minn,0x3f,sizeof minn);
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>l[i][j];
if(i>1) eadd(getid(i,j),getid(i-1,j),min(l[i][j],l[i-1][j]));
if(j>1) eadd(getid(i,j),getid(i,j-1),min(l[i][j],l[i][j-1]));
}
}
for(int i=1;i<=n*m;i++) fa[i]=i;
sort(e+1,e+1+idx,[](_edge a,_edge b){return a.w>b.w;});
for(int i=1;i<=idx;i++){
int u=e[i].u,v=e[i].v;
u=find(u),v=find(v);
if(u==v) continue;
fa[u]=v,add(u,v,e[i].w);
}
dfs(1);
cin>>q;
while(q--){
int a,b,y,c,d,z;
cin>>a>>b>>y>>c>>d>>z;
if(getid(a,b)==getid(c,d)) cout<<abs(y-z)<<"\n";
else{
int v=getmin(getid(a,b),getid(c,d));
if(v>=y||v>=z) cout<<abs(y-z)<<"\n";
else cout<<y+z-2*v<<"\n";
}
}
return 0;
}

ABCDF。

E题一直考虑最短路一类的算法,比如Floyd转移时限制\((i,k)\)和\((k,j)\)的字符串恰好相反,但是显然很多细节都是无法处理的。是真没想到BFS,有点可惜。不过由于赛时很快略过去了,所以损失不大。

F题感觉水了,思路比较自然。

G题补题时一直想的最短路,看了题解瞬间明白了,算是还能做的G了(

[题解]AtCoder Beginner Contest 394(ABC394) A~G的更多相关文章

  1. 题解 AtCoder Beginner Contest 168

    小兔的话 欢迎大家在评论区留言哦~ AtCoder Beginner Contest 168 A - ∴ (Therefore) B - ... (Triple Dots) C - : (Colon) ...

  2. [题解] Atcoder Beginner Contest ABC 270 G Ex 题解

    点我看题 G - Sequence in mod P 稍微观察一下就会发现,进行x次操作后的结果是\(A^xS+(1+\cdots +A^{x-1})B\).如果没有右边那一坨关于B的东西,那我们要求 ...

  3. AtCoder Beginner Contest 220部分题(G,H)题解

    刚开始的时候被E题卡住了,不过发现是个数学题后就开始使劲推式子,幸运的是推出来了,之后的F题更是树形DP换根的模板吧,就草草的过了,看了一眼G,随便口胡了一下,赶紧打代码,毕竟时间不多了,最后也没打完 ...

  4. [题解] Atcoder Beginner Contest ABC 265 Ex No-capture Lance Game DP,二维FFT

    题目 首先明确先手的棋子是往左走的,将其称为棋子1:后手的棋子是往右走的,将其称为棋子2. 如果有一些行满足1在2右边,也就是面对面,那其实就是一个nim,每一行都是一堆石子,数量是两个棋子之间的空格 ...

  5. AtCoder Beginner Contest 154 题解

    人生第一场 AtCoder,纪念一下 话说年后的 AtCoder 比赛怎么这么少啊(大雾 AtCoder Beginner Contest 154 题解 A - Remaining Balls We ...

  6. AtCoder Beginner Contest 177 题解

    AtCoder Beginner Contest 177 题解 目录 AtCoder Beginner Contest 177 题解 A - Don't be late B - Substring C ...

  7. KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解

    KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解 哦淦我已经菜到被ABC吊打了. A - Century 首先把当前年 ...

  8. AtCoder Beginner Contest 184 题解

    AtCoder Beginner Contest 184 题解 目录 AtCoder Beginner Contest 184 题解 A - Determinant B - Quizzes C - S ...

  9. AtCoder Beginner Contest 173 题解

    AtCoder Beginner Contest 173 题解 目录 AtCoder Beginner Contest 173 题解 A - Payment B - Judge Status Summ ...

  10. AtCoder Beginner Contest 148 题解

    目录 AtCoder Beginner Contest 148 题解 前言 A - Round One 题意 做法 程序 B - Strings with the Same Length 题意 做法 ...

随机推荐

  1. AtCoder Beginner Contest 357-D

    Problem For a positive integer \(N\), let \(V_N\) be the integer formed by concatenating \(N\) exact ...

  2. 【2020.11.30提高组模拟】删边(delete) 题解

    [2020.11.30提高组模拟]删边(delete) 题解 题意简述 给一棵树删边,每次删的代价为这条边所连的两个点的子树中最大点权值. 求删光的最小代价. \(n\le100000\). Solu ...

  3. Manim中三种函数图像类的比较

    在 Manim 库中,FunctionGraph.ImplicitFunction 和 ParametricFunction 都是用于绘制函数图像的类,但它们的适用场景.输入形式和实现方式有显著区别. ...

  4. 探秘Transformer系列之(36)--- 大模型量化方案

    探秘Transformer系列之(36)--- 大模型量化方案 目录 探秘Transformer系列之(36)--- 大模型量化方案 0x00 概述 0x01 8位量化 1.1 LLM.int8() ...

  5. tcpdump工具使用

    一.简单介绍 tcpdump命令是一款sniffer工具,它可以打印所有经过网络接口的数据包的头信息,也可以使用-w选项将数据包保存到文件中,方便以后分析. 二.使用语法 语法: tcpdump (选 ...

  6. SenseVoice部署,并调用api接口

    目录 安装Python 代码下载 虚拟环境 安装依赖 下载模型 修改启用webui.py 启用api.py 安装Python 这个网上找下教程安装下就可以,版本应该没有什么要求,我装的是3.10.7 ...

  7. Jit 报错TracingCheckError:ERROR: Graphs differed across invocations!

    问题描述 使用Tinynn将Pytorch转化为tflite时报错: 发生异常: TracingCheckError (note: full exception trace is shown but ...

  8. FastAPI WebSocket:你的双向通信通道为何如此丝滑?

    扫描二维码 关注或者微信搜一搜:编程智域 前端至全栈交流与成长 发现1000+提升效率与开发的AI工具和实用程序:https://tools.cmdragon.cn/ # 示例代码运行环境 # Pyt ...

  9. java--xml约束、tomcat服务器

    xml约束 XML语法: 规范的xml文件的基本编写规则.(由w3c组织制定的) XML约束: 规范XML文件数据内容格式的编写规则.(由开发者自行定义) DTD约束 DTD约束:语法相对简单,功能也 ...

  10. batocera添加游戏

    进入batocera系统之后,会发现就只有几个不懂什么东西的模拟器,或者FC和其它,好象没有发现可以用NS或者其它的模拟器,在此说明 一下: 整个系统至少支持73个以上模拟器,主界面没有仅因为你没有放 ...