涵盖知识点:主要考查思维和代码实现能力、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 }