返回顶部

Codeforces Round #625 (Div. 2, based on Technocup 2020 Final Round)【ABCD】(题解)(E待更新)

涵盖知识点:贪心、思维、图论

比赛链接:

https://codeforces.com/contest/1321

A:Contest for Robots

题意:有n道题。事先知道两个机器人(R,B)分别能答对哪几道。现在要分配每题得分使得机器人R一定能赢(至少1分),问怎么分配使得所有题的最高分最低。

题解:贪心。分别计算R对B错和R错B对的数量,然后把R错B对的题全部设置为1分。所以R对B错的题尽可能平均分且超过R错B对的题数即可。

Accept Code:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=110;
 4 int r[maxn],b[maxn];
 5 int main(){
 6     int n,cnt1=0,cnt2=0;
 7     cin>>n;
 8     for(int i=0;i<n;i++){
 9         cin>>r[i];
10     }
11     for(int i=0;i<n;i++){
12         cin>>b[i];
13         if(r[i]>b[i])cnt1++;
14         if(r[i]<b[i])cnt2++;
15     }
16     if(cnt1==0)cout<<"-1\n";
17     else cout<<cnt2/cnt1+1<<"\n";
18     return 0;
19 }

 

B:Journey Planning

题意:n个地点编号1~n。每个地点有一个美丽指数bi。现在要制定一个浏览顺序使得浏览过的城市的美丽指数之和最大。要求如下

  (1)浏览顺序必须为严格递增序列

  (2)相邻浏览的城市必须满足编号的差等于美丽指数的差

题解:将bi转移为bi-i即可,map记录总和,最后扫描一遍取最大值。

Accept Code:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 map<int,ll> mp;
 5 int main(){
 6     int n;
 7     cin>>n;
 8     for(int i=1;i<=n;i++){
 9         int b;
10         cin>>b;
11         mp[b-i]+=b;
12     }
13     ll ans=0;
14     for(auto i:mp){
15         ans=max(ans,i.second);
16     }
17     cout<<ans<<"\n";
18     return 0;
19 }

 

C:Remove Adjacent

题意:给定一个小写字母字符串。具体操作规则如下:若一个字母的相邻字母为它字典序中的前一个字母,则可以将这个字母删除。问最多能操作几次。

题解:注意到字符串长度仅100.所以暴力解决。顺序从z扫描到a。每次删除一个字母后记得重新扫描一遍即可。理论上最坏复杂度100*100*26

Accept Code:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int n;
 5     string w;
 6     cin >> n >> w;
 7     bool flag = true;
 8     while (flag) {
 9         flag = false;
10         for (char i = 'z';i > 'a';--i) {
11             for (int j = 0;j < w.size();++j){
12                 if (w[j] == i) {
13                     if ((j > 0 && w[j-1] == i-1) || (j+1 < w.size() && w[j+1] == i-1)) {
14                         w.erase(w.begin() + j);
15                         flag = true;
16                         break;
17                     }
18                 }
19             }
20             if (flag) break;
21         }
22     }
23     cout << n - w.size() << '\n';
24 
25 
26 }

 

D:Navigation System

题意:给定一个单向图和一个规划完的s~t路径。有一个导航仪会实时显示当前点到t的最短路径(但并不会已经规划完的路径产生影响)。如果规划的路径和导航路径不同,那么走到下一个点后,导航仪会重新规划路径。问导航仪最少和最多重新规划几次。

题解:设p为规划路径。dis[p[i]]为p[i]~t的最短距离。导航仪在如下几种情况下会重新规划:

  (1)dis[p[i]]-1≠dis[p[i+1]]。即一定不是最短路径。

  (2)存在一个不为p[i+1]的点w使得dis[p[i]]-1=dis[w]。即存在一条其他的路径为最短路径。

不难发现如果第一种情况发生,那么第二种情况一定存在。所以满足第一条即为最少的规划次数,满足第二条的即为最多的规划次数。

对于dis数组的获得逆向bfs一下即可。

Accept Code:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=2e5+10,inf=0x3f3f3f3f;
 4 int n,m,k;
 5 vector<int> edg[maxn],gde[maxn];
 6 int p[maxn],dis[maxn];
 7 void bfs(int s){
 8     queue<int> q;
 9     memset(dis,inf,sizeof dis);
10     q.push(s);
11     dis[s]=0;
12     while(!q.empty()){
13         int t=q.front();
14         q.pop();
15         for(auto i:gde[t]){
16             if(dis[i]==inf){
17                 dis[i]=dis[t]+1;
18                 q.push(i);
19             }
20         }
21     }
22 }
23 int main(){
24     cin>>n>>m;
25     for(int i=1;i<=m;i++){
26         int x,y;
27         cin>>x>>y;
28         edg[x].push_back(y);
29         gde[y].push_back(x);
30     }
31     cin>>k;
32     for(int i=1;i<=k;i++)
33         cin>>p[i];
34     bfs(p[k]);
35     int res1=0,res2=0;
36     for(int i=1;i<k;i++){
37         int u=p[i],v=p[i+1];
38         if(dis[u]!=dis[v]+1)
39             res1++;
40         for(auto w:edg[u]){
41             if(v!=w&&dis[w]+1==dis[u]) {
42                 res2++;
43                 break;
44             }
45         }
46     }
47     cout<<res1<<" "<<res2<<"\n";
48     return 0;
49 }

 

E:World of Darkraft: Battle for Azathoth

F:Reachable Strings

posted @ 2020-03-02 19:55  Charles1999  阅读(163)  评论(0编辑  收藏  举报