AtCoder Beginner Contest 378 题解
AtCoder Beginner Contest 378 题解
A - Pairing 贪心
#include<bits/stdc++.h>
using namespace std;
using i64=long long;
void Showball(){
vector<int> a(5);
for(int i=0;i<4;i++){
int x;
cin>>x;
a[x]++;
}
int cnt=0;
for(int i=1;i<=4;i++) cnt+=a[i]/2;
cout<<cnt<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t=1;
//cin>>t;
while(t--){
Showball();
}
return 0;
}
B - Garbage Collection
#include<bits/stdc++.h>
using namespace std;
using i64=long long;
void Showball(){
int n;
cin>>n;
vector<int> q(n),r(n);
for(int i=0;i<n;i++){
cin>>q[i]>>r[i];
}
int m;
cin>>m;
while(m--){
int x,d;
cin>>x>>d;
x--;
cout<<d+(q[x]+r[x]-d%q[x])%q[x]<<"\n";
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t=1;
//cin>>t;
while(t--){
Showball();
}
return 0;
}
C - Repeating
使用 map
开个桶记录一下每个数上次出现的位置即可。
#include<bits/stdc++.h>
using namespace std;
using i64=long long;
void Showball(){
int n;
cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++){
cin>>a[i];
}
map<int,int> mp;
for(int i=0;i<n;i++){
if(!mp[a[i]]) cout<<"-1 ";
else cout<<mp[a[i]]<<" ";
mp[a[i]]=i+1;
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t=1;
//cin>>t;
while(t--){
Showball();
}
return 0;
}
D - Count Simple Paths 深搜
数据范围很小,直接枚举每个点,然后从每个点开始深搜即可。标准的深搜,写法比较套路。注意 st
数组的更新。
#include<bits/stdc++.h>
using namespace std;
using i64=long long;
void Showball(){
int h,w,k;
cin>>h>>w>>k;
vector<string> a(h);
for(int i=0;i<h;i++){
cin>>a[i];
}
vector<vector<int>> st(h,vector<int>(w));
auto check=[&](int x,int y){
return (0<=x&&x<h&&0<=y&&y<w&&a[x][y]=='.'&&!st[x][y]);
};
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};
int ans=0;
function<void(int,int,int)> dfs=[&](int x,int y,int cnt){
if(cnt>=k){
ans++;
return;
}
for(int i=0;i<4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(check(xx,yy)){
st[xx][yy]=1;
dfs(xx,yy,cnt+1);
st[xx][yy]=0;
}
}
};
for(int i=0;i<h;i++){
for(int j=0;j<w;j++){
if(a[i][j]=='.') {
st[i][j]=1;
dfs(i,j,0);
st[i][j]=0;
}
}
}
cout<<ans<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t=1;
//cin>>t;
while(t--){
Showball();
}
return 0;
}
E - Mod Sigma Problem 思维
如果两层都要取模,那就非常简单,只有一层,我们先不管取模尝试化简这个式子。
考虑使用前缀和,原式 =
继续化简:
把
式子被我们化成了差的形式,因此,如果
考虑如何快速统计需要增加的
其实就是经典的逆序对问题,使用归并排序或者树状数组即可解决。
这里采用树状数组,注意,这里的数组值要对 TLE
。
所以,我们只需要偏移一位下标即可。
#include<bits/stdc++.h>
using namespace std;
using i64=long long;
void Showball(){
int n,m;
cin>>n>>m;
vector<i64> a(n+1),s(n+1);
for(int i=1;i<=n;i++){
cin>>a[i];
s[i]=(s[i-1]+a[i])%m;
}
vector<i64> tr(m+2);
auto add=[&](int x){
for(;x<=m;x+=x&-x) tr[x]++;
};
auto getsum=[&](int x){
i64 ret=0;
for(;x;x-=x&-x) ret+=tr[x];
return ret;
};
i64 tot=0,res=0;
for(int i=1;i<=n;i++){
res+=i*s[i]-tot;
tot+=s[i];
res+=1LL*m*(getsum(m)-getsum(s[i]+1));
add(s[i]+1);
}
cout<<res<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t=1;
//cin>>t;
while(t--){
Showball();
}
return 0;
}
F - Add One Edge 2 图论
要构成满足条件的环,我们只需要首尾点的度数为
那么我们只需要维护出每个点周围有多少个度数为
#include<bits/stdc++.h>
using namespace std;
using i64=long long;
void Showball(){
int n;
cin>>n;
vector<vector<int>> e(n);
vector<int> d(n);
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
u--,v--;
e[u].push_back(v);
e[v].push_back(u);
d[u]++;
d[v]++;
}
vector<int> w(n);
function<void(int,int)> dfs=[&](int u,int fa){
for(auto v:e[u]){
w[u]+=(d[v]==2);
if(v==fa) continue;
dfs(v,u);
}
};
auto bfs=[&](int st){
int ret=0;
queue<int> q;
q.push(st);
while(!q.empty()){
int u=q.front();
q.pop();
ret+=w[u];
d[u]=0;
for(auto v:e[u]){
if(d[v]!=3) continue;
q.push(v);
}
}
return ret;
};
dfs(0,-1);
i64 ans=0;
for(int i=0;i<n;i++){
if(d[i]==3){
int t=bfs(i);
ans+=1LL*t*(t-1)/2;
}
}
cout<<ans<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t=1;
//cin>>t;
while(t--){
Showball();
}
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!