AtCoder Beginner Contest 375 (A-G)

news/2024/10/21 15:34:16

AtCoder Beginner Contest 375 (A-G)

比赛链接

A - Seats

#include<bits/stdc++.h>using namespace std;using i64=long long;void Showball(){int n;string s;cin>>n>>s;int cnt=0;for(int i=0;i<n-2;i++){if(s[i]==s[i+2]&&s[i]=='#'&&s[i+1]=='.') cnt++;} cout<<cnt<<"\n";
}
int main(){ios::sync_with_stdio(false);cin.tie(nullptr);int t=1;//cin>>t;while(t--){Showball();}return 0;
}

B - Traveling Takahashi Problem

#include<bits/stdc++.h>using namespace std;using i64=long long;struct Point{int x,y;
};double dis(Point a,Point b){return hypot(a.x-b.x,a.y-b.y);
}void Showball(){int n;cin>>n;vector<Point> a(n+2);double ans=0;for(int i=1;i<n+1;i++){cin>>a[i].x>>a[i].y;}     for(int i=0;i<n+1;i++){ans+=dis(a[i],a[i+1]);}cout<<fixed<<setprecision(9)<<ans<<"\n";
}
int main(){ios::sync_with_stdio(false);cin.tie(nullptr);int t=1;//cin>>t;while(t--){Showball();}return 0;
}

C - Spiral Rotation

直接模拟时间复杂度为 \(O(n^3)\),手推发现,每次操作就是一层顺时针旋转 \(90\) 度。第 \(k\) 层就旋转 \(k\) 次即可。

#include<bits/stdc++.h>using namespace std;using i64=long long;void Showball(){int n;cin>>n;vector<vector<char>> a(n+1,vector<char>(n+1));for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>a[i][j];}} for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){int k=min(min(i,n-i+1),min(j,n-j+1))%4;if(k==0) cout<<a[i][j];else if(k==1) cout<<a[n-j+1][i];else if(k==2) cout<<a[n-i+1][n-j+1];else cout<<a[j][n-i+1];}cout<<"\n";}}
int main(){ios::sync_with_stdio(false);cin.tie(nullptr);int t=1;//cin>>t;while(t--){Showball();}return 0;
}

D - ABA

思路

枚举中间位置,以及两边的字母即可,直接前缀和维护每个字母出现次数,然后乘法原理简单处理即可。

#include<bits/stdc++.h>using namespace std;using i64=long long;void Showball(){string s;cin>>s;int n=s.size();s="?"+s;vector<array<int,26>> pre(n+1);for(int i=1;i<=n;i++){for(int j=0;j<26;j++) pre[i][j]=pre[i-1][j];pre[i][s[i]-'A']++;}i64 ans=0;for(int i=1;i<=n;i++){for(int j=0;j<26;j++){ans+=1LL*pre[i-1][j]*(pre[n][j]-pre[i][j]);}}cout<<ans<<"\n";
}
int main(){ios::sync_with_stdio(false);cin.tie(nullptr);int t=1;//cin>>t;while(t--){Showball();}return 0;
}

E - 3 Team Division DP

思路

考虑 \(dp\), 令 \(f_{i,j,k}\) 表示考虑前 \(i\) 个人,并且第一组强度之和为 \(j\), 第二组强度之和为 \(k\) 时所需的最少换队人数。

状态转移考虑第 \(i\) 个人的三种选择即可。具体看代码实现。

#include<bits/stdc++.h>using namespace std;using i64=long long;int f[510][510][510];
void Showball(){int n;cin>>n;vector<int> a(n+1),b(n+1);int sum=0;for(int i=1;i<=n;i++){cin>>a[i]>>b[i];sum+=b[i];}if(sum%3) return cout<<"-1\n",void();memset(f,0x3f,sizeof f);f[0][0][0]=0;for(int i=1;i<=n;i++){for(int j=0;j<=500;j++){for(int k=0;k<=500;k++){if(j>=b[i]){f[i][j][k]=min(f[i][j][k],f[i-1][j-b[i]][k]+(a[i]!=1));}if(k>=b[i]){f[i][j][k]=min(f[i][j][k],f[i-1][j][k-b[i]]+(a[i]!=2));}f[i][j][k]=min(f[i][j][k],f[i-1][j][k]+(a[i]!=3));}}}sum/=3;int ans=f[n][sum][sum];if(ans>0x3f3f3f3f/2) ans=-1;cout<<ans<<"\n";
}
int main(){ios::sync_with_stdio(false);cin.tie(nullptr);int t=1;//cin>>t;while(t--){Showball();}return 0;
}

F - Road Blocked 最短路

考虑到删除边不好操作,并且最多只会删除 \(300\) 条边。我们可以考虑离线处理。把所有的操作存起来,倒着进行加边处理即可。每次加边,就考虑新加的边来做端点的情况来更新最短路即可。多源最短路用 \(Floyd\) 即可。

#include<bits/stdc++.h>using namespace std;using i64=long long;const i64 inf = 0x3f3f3f3f3f3f3f3f;
void Showball(){int n,m,q;cin>>n>>m>>q;vector<vector<i64>> f(n+1,vector<i64>(n+1,inf));vector<array<i64,3>> e(m),Q(q);for(int i=1;i<=n;i++) f[i][i]=0;for(int i=0;i<m;i++){int u,v,w;cin>>u>>v>>w;e[i]={u,v,w};}vector<int> st(m);for(int i=0;i<q;i++){int op,x,y=0;cin>>op>>x;if(op==1){st[x-1]=1;}else{cin>>y;}Q[i]={op,x,y};}for(int i=0;i<m;i++){if(!st[i]){auto [u,v,w]=e[i];f[u][v]=min(f[u][v],w); f[v][u]=min(f[v][u],w); }}for(int k=1;k<=n;k++){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){f[i][j]=min(f[i][j],f[i][k]+f[k][j]);}}}vector<i64> ans(q);for(int i=q-1;i>=0;i--){auto [op,x,y]=Q[i];if(op==1){auto [u,v,w]=e[x-1];f[u][v]=min(f[u][v],w); f[v][u]=min(f[v][u],w);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){f[i][j]=min({f[i][j],f[i][u]+f[v][j]+w,f[i][v]+f[u][j]+w});}} }else{ans[i]=f[x][y];}}for(int i=0;i<q;i++){if(Q[i][0]==2) cout<<(ans[i]>=inf?-1:ans[i])<<"\n";}
}
int main(){ios::sync_with_stdio(false);cin.tie(nullptr);int t=1;//cin>>t;while(t--){Showball();}return 0;
}

G - Road Blocked 2 Dijkstra+Tarjan

首先判断这条边是否出现在 \(1-n\) 的最短路上,如果没有出现,那就没有影响。

判断方法,我们只需要用 \(Dijkstra\) 分别维护出 \(1\) 到所有点最短路 $d_1 $和 $n $ 到所有点的最短路 \(d_2\)

令该条边为 \(u-v\)。权值为 \(w\)\(1-n\) 之间的最短路为 \(dis\) 。那么如果 \(d1_u+d2_v+w = dis || d1_v+d2_u+w = dis\)

说明改变在最短路上。

接下来考虑在最短路上的边。很明显只有该边是割边的时候,删到该边才会产生影响。

因此,我们将所有在最短路上的边存下来,重新建图,跑一遍 \(tarjan\) 求一下割边即可。

思路比较简单,就是模板组合题。很适合练手。

#include<bits/stdc++.h>
using namespace std;
using i64=long long;
void Showball(){int n,m;cin>>n>>m;vector<vector<array<int,2>>> e(n);vector<array<int,3>> edge(m);for(int i=0;i<m;i++){int u,v,w;cin>>u>>v>>w;u--;v--;edge[i]={u,v,w};e[u].push_back({v,w});e[v].push_back({u,w});}        vector<i64> d1(n),d2(n);auto dijkstra=[&](int s){vector<i64> d(n,1e18);vector<int> st(n);d[s]=0;priority_queue<pair<i64,int>,vector<pair<i64,int>>,greater<pair<i64,int>>> pq;pq.push({0,s});while(!pq.empty()){auto [dis,u]=pq.top();pq.pop();if(st[u]) continue;st[u]=1;for(auto [v,w]:e[u]){if(d[v]>dis+w){d[v]=dis+w;pq.push({d[v],v});}}}return d;};d1=dijkstra(0);i64 dis=d1[n-1];d2=dijkstra(n-1);vector<int> ans(m);vector<array<int,3>> vec;vector<vector<array<int,2>>> e2(n);for(int i=0;i<m;i++){auto [u,v,w]=edge[i];if(d1[u]+d2[v]+w==dis||d1[v]+d2[u]+w==dis){e2[u].push_back({v,1});e2[v].push_back({u,1});vec.push_back({u,v,i});}}vector<int> dfn(n),low(n);int tot=0;map<pair<int,int>,int> mp;function<void(int,int)> tarjan=[&](int u,int fa){dfn[u]=low[u]=++tot;for (auto [v,w]:e2[u]){if(!dfn[v]){tarjan(v, u);low[u]=min(low[u],low[v]);if (low[v]>dfn[u])mp[{u,v}]=1,mp[{v,u}]=1;}else if(v!=fa){low[u]=min(low[u],dfn[v]);}}};for(int i=0;i<n;i++){if(!dfn[i]) tarjan(i,-1);}for(auto [u,v,id]:vec){if(mp[{u,v}]) ans[id]=1;}for(auto x:ans) cout<<(x?"Yes\n":"No\n");
}
int main(){ios::sync_with_stdio(false);cin.tie(nullptr);int t=1;//cin>>t;while(t--){Showball();}return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

IIC通讯协议笔记

iic通讯协议片上外设iic主发送器主发送器通讯过程 发送开始位后等待EVT5,发送从机(slave)地址等待EVT6和发送要写入从机的寄存器等待EVT8,发送数据等待EVT8_2片上外设主接收器发送过程接收过程

【C#】【DevExpress】自定义单元格右键菜单,去除单元格编辑时,载入系统的默认菜单

使用GridView,自定义单元格的右击菜单,可以通过监听事件PopupMenuShowing,实现新增菜单。1 private void gridView1_PopupMenuShowing(object sender, DevExpress.XtraGrid.Views.Grid.PopupMenuShowingEventArgs e)2 {3 GridView view = sender as GridView;4 if (v…

2024年游戏买量应该怎么玩?

App中运行小游戏的技术价值和业务价值都是显著的:通过小程序容器技术,承载多样化的小游戏运行在自有App内,实现跨平台的游戏资源共享,降低买量成本,此为「降本」。进一步的,在App内快速引入多小游戏应用,为用户提供多样化的内容,以提升App内用户体验和留存率,增强用户…

JAVA基础之十-不常用但是又希望能看懂的关键字/保留字

对于绝大部分JAVA工程师而言,大部分的关键字也是能够看懂的,但还是相当一部分比较不常见的关键字,妨碍了代码阅读。 本文力图收集一些个人认为在CRUD机械工作中可能比较少见的一些关键字/保留字。 此类关键字主要用于修饰方法和类。 收集过程会持续一段时间,现在暂时没有时间…

django admin 后台中添加自定义的 html 页面

实现效果配置 简历模板html 文件{% extends "admin/base_site.html" %}{% block content %} <h1>自定义 HTML 页面</h1> <p>{{ your_variable }}</p> {% endblock %}admin 中添加代码, 主要是 get_urls 以及 对应的的视图from django.urls i…

国内外开源项目管理工具软件有哪些

不错的开源项目管理工具软件有:1. Redmine;2. Taiga;3. OpenProject;4. Tuleap;5. Odoo Project。比如Redmine是一款受到广大用户赞誉的开源项目管理工具,已被像GitHub、NASA和CERN这样的知名客户所采用。其核心能力在于灵活的问题跟踪和多项目管理。开源项目管理软件特别…

018 姓名案例

这么写有点小问题,效率不高,我们考虑计算属性来做

malloc底层实现以及和new的比较

背景: 前几天去面试,被问到了一个问题:“malloc的底层实现是怎样的? 怎样防止内存碎片?” 当时答的不够好,现在再整理一下。 (本文档通过收集整理网上博客而来。先挖个坑,等有时间了去看一下《深入理解操作系统》的第九章虚拟内存,再重新整理一篇) 内存布局 Linux中每…