Codeforces Round #605 (Div. 3) ABCDE 题解
Posted vbel
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #605 (Div. 3) ABCDE 题解相关的知识,希望对你有一定的参考价值。
A. Three Friends
分析
首先在直线上三点两两间距离之和等于最远的两个点距离的两倍.因此,只需要控制距离最远的两个点即可.
代码
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 int main() 6 { 7 int T; 8 cin>>T; 9 while(T--) 10 { 11 int num[3]; 12 for(int i=0;i<3;i++) 13 scanf("%d",&num[i]); 14 sort(num,num+3); 15 if(num[2]-num[0]<=2) 16 printf("0 "); 17 else 18 printf("%d ",(num[2]-num[0]-2)*2); 19 } 20 return 0; 21 }
B. Snow Walking Robot
分析
统计以下输入字符串‘U‘ ‘D‘ ‘L‘ ‘R‘的数量,并让‘U‘的数量和‘D‘的数量相等,‘L‘的数量和‘R‘的数量相等.一般情况下只要按顺序输出‘R‘‘U‘‘L‘‘D‘(即绕一圈)就可以了.注意以下特殊情况,就是只有‘R‘和‘L‘且各自数量大于1,此时是没答案的.对‘U‘‘D‘同理.
代码
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 typedef long long LL; 5 6 int dex[200]; 7 8 int main() 9 { 10 int T; 11 cin>>T; 12 while(T--) 13 { 14 dex[‘L‘]=dex[‘R‘]=dex[‘U‘]=dex[‘D‘]=0; 15 string s; 16 cin>>s; 17 for(int i=0;i<s.size();i++) 18 dex[s[i]]++; 19 int dec=0; 20 if(dex[‘R‘]>dex[‘L‘]) 21 { 22 dec+=dex[‘R‘]-dex[‘L‘]; 23 dex[‘R‘]=dex[‘L‘]; 24 } 25 else 26 { 27 dec+=dex[‘L‘]-dex[‘R‘]; 28 dex[‘L‘]=dex[‘R‘]; 29 } 30 if(dex[‘U‘]>dex[‘D‘]) 31 { 32 dec+=dex[‘U‘]-dex[‘D‘]; 33 dex[‘U‘]=dex[‘D‘]; 34 } 35 else 36 { 37 dec+=dex[‘D‘]-dex[‘U‘]; 38 dex[‘D‘]=dex[‘U‘]; 39 } 40 if(dex[‘L‘]>1&&dex[‘U‘]==0) 41 { 42 dec+=(dex[‘L‘]-1)*2; 43 printf("%d RL ",s.size()-dec); 44 } 45 else if(dex[‘U‘]>1&&dex[‘L‘]==0) 46 { 47 dec+=(dex[‘U‘]-1)*2; 48 printf("%d UD ",s.size()-dec); 49 } 50 else 51 { 52 printf("%d ",s.size()-dec); 53 for(int i=0;i<dex[‘R‘];i++) 54 printf("R"); 55 for(int i=0;i<dex[‘U‘];i++) 56 printf("U"); 57 for(int i=0;i<dex[‘L‘];i++) 58 printf("L"); 59 for(int i=0;i<dex[‘D‘];i++) 60 printf("D"); 61 cout<<endl; 62 } 63 } 64 return 0; 65 }
C. Yet Another Broken Keyboard
分析
按不可用的字母将原字符串分成若干个字符串,分开后的字符串的字母均为可用的,接下来只需要逐个统计每个字符串的子串数量即可.一个字符串的子串数量为(1+n)*n/2.
代码
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 typedef long long LL; 5 6 bool used[26]; 7 8 int main() 9 { 10 int N,K; 11 scanf("%d %d",&N,&K); 12 string s; 13 cin>>s; 14 for(int i=0;i<K;i++) 15 { 16 char x; 17 cin>>x; 18 used[x-‘a‘]=true; 19 } 20 LL ans=0;int cnt=0; 21 for(int i=0;i<s.size();i++) 22 { 23 if(!used[s[i]-‘a‘]) 24 { 25 ans+=(LL)(cnt+1)*cnt/2; 26 cnt=0; 27 } 28 else cnt++; 29 } 30 ans+=(LL)(cnt+1)*cnt/2; 31 printf("%lld ",ans); 32 return 0; 33 }
D. Remove One Element
分析
设两个数组l[i],r[i],1<=i<=n,分别表示以i为开始的最长递增长度,以i为结尾的最长递增长度.刚开始全都是1.
l[i]数组只需要 i从N-1->1,if(a[i]<a[i+1]) l[i]=l[i+1]+1 处理一遍即可
r[i]数组只需要 i从 2->N,if(a[i]>a[i-1]) r[i]=r[i-1]+1 处理一遍即可
从以上处理出来的值可知未删减时最长递增长度,删减后的最长递增长度由以下操作可得:
删减i(i>1&&i<N)后,如果a[i-1]<a[i+1],得到的新长度为r[i-1]+l[i+1]
代码
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 typedef long long LL; 5 const int INF=0x3f3f3f3f; 6 7 int a[200000]; 8 int l[200000]; 9 int r[200000]; 10 11 int main() 12 { 13 int N; 14 cin>>N; 15 for(int i=0;i<N;i++) 16 scanf("%d",&a[i]); 17 for(int i=0;i<N;i++) 18 l[i]=r[i]=1; 19 20 int ans=1; 21 22 for(int i=N-2;i>=0;i--) 23 if(a[i]<a[i+1]) 24 { 25 l[i]=l[i+1]+1; 26 ans=max(ans,l[i]); 27 } 28 29 for(int i=1;i<N;i++) 30 if(a[i]>a[i-1]) r[i]=r[i-1]+1; 31 32 for(int i=1;i<N-1;i++) 33 if(a[i+1]>a[i-1]) 34 ans=max(ans,r[i-1]+l[i+1]); 35 36 cout<<ans<<endl; 37 return 0; 38 }
E. Nearest Opposite Parity
分析
依题意可以构造一个图,先将图的边反向,然后把所有奇数点偶数点分开, 所有点的答案默认为-1,要求奇数点的答案,只需要从偶数点开始跑多源bfs即可,即bfs第一步就包含所有的偶数点.同理可求偶数点的答案.
代码
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 typedef long long LL; 5 typedef pair<int,int> P; 6 const int INF=0x3f3f3f3f; 7 8 int a[200000]; 9 int ans[200000]; 10 vector<int> edge[200000]; 11 queue<P> que; 12 bool vis[200000]; 13 14 void bfs() 15 { 16 while(que.size()) 17 { 18 P p=que.front();que.pop(); 19 int x=p.first,dis=p.second; 20 for(int i=0;i<edge[x].size();i++) 21 { 22 int to=edge[x][i]; 23 if(!vis[to]) 24 { 25 vis[to]=true; 26 ans[to]=dis+1; 27 que.push(P{to,dis+1}); 28 } 29 } 30 } 31 } 32 33 int main() 34 { 35 int N; 36 cin>>N; 37 for(int i=0;i<N;i++) 38 { 39 scanf("%d",&a[i]); 40 if(i+a[i]<N) edge[i+a[i]].push_back(i); 41 if(i-a[i]>=0) edge[i-a[i]].push_back(i); 42 } 43 for(int i=0;i<N;i++) 44 ans[i]=INF; 45 for(int i=0;i<N;i++) 46 if(a[i]&1) 47 { 48 vis[i]=true; 49 que.push(P(i,0)); 50 } 51 else vis[i]=false; 52 bfs(); 53 for(int i=0;i<N;i++) 54 if(!(a[i]&1)) 55 { 56 vis[i]=true; 57 que.push(P(i,0)); 58 } 59 else vis[i]=false; 60 bfs(); 61 for(int i=0;i<N;i++) 62 if(ans[i]==INF) printf("-1%c",i==N-1?‘ ‘:‘ ‘); 63 else printf("%d%c",ans[i],i==N-1?‘ ‘:‘ ‘); 64 return 0; 65 }
以上是关于Codeforces Round #605 (Div. 3) ABCDE 题解的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #605 (Div. 3) ABCDE 题解
Codeforces Round #605(Div3)A~E
Codeforces Round #605 (Div. 3) E. Nearest Opposite Parity
Codeforces Round #605 (Div. 3) E - Nearest Opposite Parity
Codeforces Round #605 (Div. 3) F. Two Bracket Sequences 三维dp
Codeforces Round #605 (Div. 3) E - Nearest Opposite Parity (超级源点)