• 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
    ";
    17     else cout<<cnt2/cnt1+1<<"
    ";
    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<<"
    ";
    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() << '
    ';
    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<<"
    ";
    48     return 0;
    49 }

    E:World of Darkraft: Battle for Azathoth

    F:Reachable Strings

  • 相关阅读:
    【原创】go语言学习(十六)接口
    【原创】go语言学习(十五)IO操作2
    【原创】go语言学习(十四)IO操作1
    【原创】go语言学习(十三)struct介绍2
    【原创】go语言学习(十二)struct介绍1
    【原创】go语言学习(十一)package简介
    【原创】sed正则表达式替换
    【原创】go语言学习(十)Map类型
    【原创】go语言学习(九)指针类型
    【原创】go语言学习(八)切片
  • 原文地址:https://www.cnblogs.com/charles1999/p/12397684.html
Copyright © 2020-2023  润新知