Codeforces Round #620 (Div. 2)【A、B、C、D、E】题解(持续更新)

涵盖知识点:主要考查思维和代码实现能力、LCA。

比赛链接:

https://codeforces.com/contest/1304

A:Two Rabbits

题意:两只兔子分别在x和y位置,左边的兔子每次往右跳a,右边的兔子每次往左跳b,问是否会在某一点相遇。

题解:算间隔距离是否为a+b的倍数即可。

AC代码:

 1 //A
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 
 5 int main(){
 6     int t;
 7     cin>>t;
 8     while(t--){
 9         int x,y,a,b;
10         cin>>x>>y>>a>>b;
11         int len=y-x;
12         if(len%(a+b)==0){
13             cout<<len/(a+b)<<"
";
14         }else{
15             cout<<"-1
";
16         }
17     }
18     return 0;
19 }

B:Longest Palindrome

题意:给长度为m的n个串,问最多选几个构成回文串。

题解:暴力寻找配对回文串分别加在答案的头和尾,最后再遍历一遍没有配对的是否含有自身就是回文的串,有则放正中间

AC代码:

 1 //B
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 string s[110];
 5 bool vis[110];
 6 int main(){
 7     int n,m;
 8     cin>>n>>m;
 9     for(int i=0;i<n;i++){
10         cin>>s[i];
11     }
12     string ans="";
13     for(int i=0;i<n;i++){
14         if(vis[i])continue;
15         string tmp=string(s[i].rbegin(),s[i].rend());
16         for(int j=i+1;j<n;j++){
17             if(vis[j])continue;
18             if(s[j]==tmp){
19                 vis[i]=vis[j]=true;
20                 ans=s[i]+ans;
21                 ans=ans+s[j];
22             }
23         }
24     }
25     for(int i=0;i<n;i++){
26         if(!vis[i]){
27             string tmp=string(s[i].rbegin(),s[i].rend());
28             if(s[i]==tmp){
29                 cout<<ans.length()+m<<"
";
30                 for(int j=0;j<ans.length()/2;j++){
31                     cout<<ans[j];
32                 }
33                 cout<<s[i];
34                 for(int j=ans.length()/2;j<ans.length();j++){
35                     cout<<ans[j];
36                 }
37                 cout<<"
";
38                 return 0;
39             }
40         }
41     }
42     cout<<ans.length()<<"
";
43     if(ans.length())cout<<ans<<"
";
44     return 0;
45 }

C:Air Conditioner

题意:每秒可以控制室内温度+1,-1或者不变。每个客人来的时候需要满足室内温度在自己的舒适区间内,问是否可以完成任务。

题解:算出每个人来的时候的可以控制的温度区间,观察是否存在温度区间内的温度在自己的舒适区间内,并更新当前的温度区间为[两者左区间的较大值,两者右区间的较小值]。遍历一遍即可。

AC代码:

 1 //C
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 
 5 struct Node{
 6     int t,l,r;
 7 }p[110];
 8 void solve(){
 9     int n,m;
10     cin>>n>>m;
11     Node timer={0,m,m};
12     for(int i=0;i<n;i++){
13         cin>>p[i].t>>p[i].l>>p[i].r;
14     }
15     int lst=0;
16     for(int i=0;i<n;i++){
17         timer={p[i].t,max(p[i].l,timer.l-p[i].t+timer.t),min(p[i].r,timer.r+p[i].t-timer.t)};
18         if(timer.l>p[i].r||timer.r<p[i].l){
19             cout<<"NO
";
20             return;
21         }
22     }
23     cout<<"YES
";
24 }
25 int main(){
26     int t;
27     cin>>t;
28     while(t--){
29         solve();
30     }
31     return 0;
32 }

D:Shortest and Longest LIS

题意:给n个数(1-n)之间组成串的相邻两数的大小关系,求使得LIS最小和最大的两种序列。

题解:使LIS最小即小于号往大取,使LIS最大即大于号往小取即可。主要考察代码实现的能力。

AC代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 2e5 + 5;
 4 char s[N];
 5 int n, a[N];
 6 void getmax() {
 7     int L = 0, pre = 0;
 8     for(int i = 1; i <= n; i++) {
 9         if(s[i] == '>') continue;
10         else {
11             for(int j = i; j > pre; j--) a[j] = ++L;
12             pre = i;
13         }
14     }
15     for(int i = 1; i <= n; i++) printf("%d ", a[i]);
16     printf("
");
17 }
18 void getmin() {
19     int L = n + 1, pre = 0;
20     for(int i = 1; i <= n; i++) {
21         if(s[i] == '<') continue;
22         else {
23             for(int j = i; j > pre; j--) a[j] = --L;
24             pre = i;
25         }
26     }
27     for(int i = 1; i <= n; i++) printf("%d ", a[i]);
28     printf("
");
29 }
30 
31 int main() {
32     int T; scanf("%d", &T);
33     while(T--) {
34         scanf("%d", &n);
35         scanf(" %s", s + 1);
36         getmin();
37         getmax();
38     }
39 }

E:1-Trees and Queries

题意:给一棵树,q次询问,每次在x,y之间临时加一条边,问a是否可以经过k步到达b。

题解:设a到b的距离为len,则只需要len<=k并且奇偶性相同即可(两点间重复行走不影响结果)。a到b的距离分三种情况讨论:a-b、a-x-y-b、a-y-x-b。关于树上最短距离可以用倍增的LCA求解。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 const int maxd=20;
 5 vector<int> edg[maxn];
 6 
 7 int fa[maxn][maxd];
 8 int deg[maxn];
 9 
10 void bfs(int root){
11     queue<int> q;
12     deg[root]=0;
13     fa[root][0]=root;
14     q.push(root);
15     while(!q.empty()){
16         int u=q.front();
17         q.pop();
18         for(int i=1;i<maxd;i++){
19             fa[u][i]=fa[fa[u][i-1]][i-1];
20         }
21         for(auto v:edg[u]){
22             if(v==fa[u][0])continue;
23             deg[v]=deg[u]+1;
24             fa[v][0]=u;
25             q.push(v);
26         }
27     }
28 }
29 int lca(int u,int v){
30     if(deg[u]>deg[v])swap(u,v);
31     int hu=deg[u],hv=deg[v];
32     for(int det=hv-hu,i=0;det;det>>=1,i++){
33         if(det&1)v=fa[v][i];
34     }
35     if(u==v)return u;
36     for(int i=maxd-1;i>=0;i--){
37         if(fa[u][i]==fa[v][i])continue;
38         u=fa[u][i],v=fa[v][i];
39     }
40     return fa[u][0];
41 }
42 bool check(int x,int y){
43     return y>=x&&x%2==y%2;
44 }
45 int dis(int u,int v){
46     return deg[u]+deg[v]-deg[lca(u,v)]*2;
47 }
48 int main(){
49     int n;
50     cin>>n;
51     for(int i=1;i<n;i++){
52         int u,v;
53         cin>>u>>v;
54         edg[u].push_back(v);
55         edg[v].push_back(u);
56     }
57     bfs(1);
58     int q;
59     cin>>q;
60     while(q--){
61         int x,y,a,b,k;
62         cin>>x>>y>>a>>b>>k;
63         if(check(dis(a,b),k)||check(dis(a,x)+dis(y,b)+1,k)||check(dis(a,y)+dis(x,b)+1,k))
64             cout<<"YES
";
65         else
66             cout<<"NO
";
67     }
68     return 0;
69 }

F1:Animal Observation (easy version)

F2:Animal Observation (hard version)

原文地址:https://www.cnblogs.com/charles1999/p/12316528.html