Codeforces补题2020.3.2 (Round625 Div2)

A.Contest for Robots

Polycarp正在筹备第一届机器人编程竞赛。其中有n个问题,许多机器人都将参与其中。每个解决我的问题的机器人都会得到pi积分,竞赛中每个机器人的得分将计算为我解决的所有问题的pi的总和。对于每个问题,pi是一个不小于1的整数。

两家专门解决问题的机器人制造公司,“ Robo-Coder Inc.”。和“ BionicSolver Industries”也将注册两个机器人(每个公司一个)。 Polycarp知道这些公司生产的机器人的优缺点,因此,对于每个问题,他都精确地知道每个机器人在比赛中是否会解决。知道了这一点,他可以尝试预测结果-或操纵它们。

由于某种原因(绝对不能涉及贿赂),Polycarp想要“ Robo-Coder Inc.”。机器人在竞争中胜过“ BionicSolver Industries”机器人。 Polycarp希望以“ Robo-Coder Inc.”这样的方式设置pi的值。机器人比“ BionicSolver Industries”机器人要获得更多的积分。但是,如果pi的值很大,可能看起来非常可疑-因此Polycarp希望在所有问题上都将pi的最大值最小化。您可以帮助Polycarp确定为解决问题而给定的点数的最小可能上限吗?

输入值 第一行包含一个整数n(1≤n≤100)-问题的数量。

第二行包含n个整数r1,r2,...,rn(0≤ri≤1)。 ri = 1表示“ Robo-Coder Inc.”机器人将解决第i个问题,ri = 0表示它将不解决第i个问题。

第三行包含n个整数b1,b2,...,bn(0≤bi≤1)。 bi = 1表示“ BionicSolver Industries”机器人将解决第i个问题,bi = 0表示将不解决第i个问题。

输出量 如果是“ Robo-Coder Inc.”机器人不能以任何方式胜过“ BionicSolver Industries”机器人,打印一个整数-1。

否则,如果pi的所有值均以“ Robo-Coder Inc.”的方式设置,则打印maxi = 1npi的最小可能值。机器人比“ BionicSolver Industries”机器人要获得更多的积分。

题解:

简单模拟。

Codeforces补题2020.3.2 (Round625 Div2)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1014;
int a[maxn],b[maxn];
int main () {
    int N;
    scanf("%d",&N);
    int ans1=0;
    int ans2=0;
    for (int i=1;i<=N;i++)
        scanf("%d",&a[i]),ans1+=a[i]==1;
    for (int i=1;i<=N;i++)
        scanf("%d",&b[i]),ans2+=b[i]==1;
    int dif=0;
    for (int i=1;i<=N;i++) 
        if (a[i]&&!b[i]) dif++;
    if (ans1>ans2) {
        printf("1\n");
        return 0;
    }
    if (ans1<=ans2) {
        if (dif==0) {
            printf ("-1\n");
            return 0;
        }
        int tmp=ans2-ans1+1;
        printf ("%d\n",(tmp+dif-1)/dif+1);
    }
    return 0;
}
View Code

 

B.Journey Planning

Tanya希望穿越Berland的城市。 Berland的主要铁路线上有n个城市,这些城市的编号从1到n。

Tanya计划她的旅程如下。首先,她将选择某个城市c1来开始自己的旅程。她将访问它,然后去另一个城市c2> c1,然后去另一个城市c3> c2,依此类推,直到她选择结束在某个城市ck> ck-1的旅程。因此,应严格增加访问城市的顺序[c1,c2,…,ck]。

Tanya访问城市的时间顺序还有其他一些限制。每个城市我都有一个与之相关的美丽价值bi。如果Tanya的旅程中只有一个城市,那么这些美丽价值就意味着没有其他限制。但是,如果序列中有多个城市,则对于任何一对相邻城市ci和ci + 1,条件ci + 1-ci = bci + 1-bci必须成立。

例如,如果n = 8且b = [3,4,4,6,6,7,8,9],则可以通过以下三种方式来计划行程:

c = [1,2,4]; c = [3,5,6,8]; c = [7](由一个城市组成的旅程也是有效的)。 上面没有列出一些计划旅程的其他方式。

Tanya希望自己的旅程尽可能美丽。整个旅程的美丽价值是所有拜访城市的美丽价值总和。您可以帮助她选择最佳计划,即最大化旅程的美丽价值吗?

输入值 第一行包含一个整数n(1≤n≤2⋅105)-Berland中的城市数。

第二行包含n个整数b1,b2,...,bn(1≤bi≤4⋅105),其中bi是第i个城市的美值。

输出量 打印一个整数-Tanya可以选择的最大旅程之美。

题解:

a[i]-a[j]=i-j;

a[i]-i=a[j]-j

简单的公式推导,然后哈希处理。

Codeforces补题2020.3.2 (Round625 Div2)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+14;
typedef long long ll;
int a[maxn];
ll l[maxn];
vector<int> g[maxn];
ll maxValue=0;
int main () {
    int N;
    scanf("%d",&N);
    for (int i=1;i<=N;i++) 
        scanf("%d",&a[i]);
    for (int i=1;i<=N;i++) {
        l[a[i]-i]+=a[i];
        maxValue=max(maxValue,l[a[i]-i]);
    }
    printf ("%lld\n",maxValue);
    return 0;
}
View Code

 

C.Remove Adjacent

您将得到一个由小写拉丁字母组成的字符串s。令s的长度为| s |。您可以对该字符串执行一些操作。

在一个操作中,如果至少相邻的一个字符是si的拉丁字母中的前一个字母,则可以选择某个索引i并删除s(si)的第i个字符。例如,b的前一个字母是a,s的前一个字母是r,字母a没有前一个字母。请注意,每次删除后,字符串的长度将减少一。因此,索引i应该满足1≤i≤| s |的条件在每个操作过程中。

对于字符si,相邻字符为si-1和si + 1。 s的第一个和最后一个字符都只有一个相邻字符(除非| s | = 1)。

考虑以下示例。令s = bacabcab。

在第一步中,因为s2 = a,所以可以删除第一个字符s1 = b。然后,字符串变为s = acabcab。 在第二步中,因为s4 = b,所以可以删除第五个字符s5 = c。然后,字符串变为s = acabab。 在第三步中,您可以删除第六个字符s6 ='b',因为s5 = a。然后,字符串变为s = acaba。 在第四步中,您唯一可以删除的字符是s4 = b,因为s3 = a(或s5 = a)。该字符串变为s = acaa,您将无法对其进行任何操作。 您的任务是找到最佳选择操作顺序后可以删除的最大字符数。

输入值 输入的第一行包含一个整数| s | (1≤| s |≤100)-s的长度。

输入的第二行包含一个由| s |组成的字符串s。小写拉丁字母。

输出量 打印一个整数-如果选择最佳移动顺序,则可以删除的最大字符数。

题解:

直接暴力,每一遍遍历都会删除字符,直接遍历一百遍就可以了。

Codeforces补题2020.3.2 (Round625 Div2)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+14;
int main () {
    int N;
    scanf("%d",&N);
    string s;
    cin>>s;
    for (int i=25;i>=0;i--) {
        for (int j=0;j<=100;j++) {
            for (int k=0;k<s.length();k++) {
                if (s[k]-'a'==i) {
                    if (s[k-1]-'a'==i-1||s[k+1]-'a'==i-1)
                        s.erase(k,1),--k;
                }
            }
        }
    }
    printf ("%d\n",N-s.length());
    return 0;
}
View Code

 

D.Navigation System

Bertown的地图可以表示为一组n个十字路口,编号从1到n,并由m条单向道路连接。可以沿着道路从任何路口移动到任何其他路口。从一个十字路口到另一十字路口的某条路径的长度是一个人必须沿着该路径穿越的道路数量。从一个交叉点v到另一交叉点u的最短路径是在v中开始,在u中结束并且在所有此类路径中具有最小长度的路径。

Polycarp生活在十字路口s附近,并在十字路口t附近的建筑物中工作。他每天都从小汽车到小汽车。今天,他选择了以下方式前往工作场所:p1,p2,...,pk,其中p1 = s,pk = t,并且此序列的所有其他元素都是中间交叉点,按Polycarp到达它们的顺序列出。 carp果从未两次到达同一路口,因此该序列的所有元素都是成对的。请注意,您事先知道了Polycarp的路径(它是固定的),并且不一定是从s到t的最短路径之一。

Polycarp的汽车上装有复杂的导航系统。让我们描述一下它是如何工作的。当Polycarp在交叉点s开始旅程时,系统会选择从s到t的最短路径,并将其显示给Polycarp。让我们将所选路径中的下一个交叉点表示为v。如果Polycarp选择沿着从s到v的道路行驶,那么导航器会向他显示相同的最短路径(显然,他到达此交叉点后即从v开始)。但是,如果Polycarp选择开车到另一个路口w,导航器将重建路径:Polycarp到达w后,导航系统会选择从w到t的最短路径,并将其显示给Polycarp。继续相同的过程,直到Polycarp到达t:如果Polycarp沿着系统建议的道路移动,它将保持已建立的最短路径;但是如果Polycarp选择其他路径,则系统将按照相同的规则重建路径。

这是一个例子。假设Bertown的地图如下所示,并且Polycarp沿着路径[1,2,3,4](s = 1,t = 4)行驶:

通过链接http://tk.codeforces.com/a.png查看图片

当Polycarp从1开始时,系统会选择从1到4的最短路径。只有一个这样的路径,即[1,5,4];否则,只有一个。 Polycarp选择开车到2,而不是沿着系统选择的路径行驶。当Polycarp到达2时,导航器通过选择从2到4的最短路径来重建路径,例如[2,6,4](注意,它可以选择[2,3,4]); Polycarp选择开车到3,这不是沿着系统选择的路径。当Polycarp到达3时,导航器通过从3到4选择唯一的最短路径[3,4]来重建路径。 Polycarp沿着导航器选择的路线到达4,因此系统无需重建任何东西。 总体而言,在这种情况下,我们进行了两次重建。请注意,如果系统在第二步中选择[2,3,4]而不是[2,6,4],则将仅进行1次重建(因为Polycarp沿着路径行进,因此系统会保留路径[3, 4])。

该示例向我们显示,即使Bertown的地图和Polycarp选择的路径保持不变,重建的次数也可能不同。有了这些信息(地图和Polycarp的路径),您是否可以确定旅途中可能进行的最小和最大数量的重建?

输入值 第一行包含两个整数n和m(2≤n≤m≤2⋅105),分别是Bertown的交叉路口和单向道路的数量。

然后,沿着m条线,每条线描述一条道路。每行包含两个整数u和v(1≤u,v≤n,u≠v),表示从交叉点u到交叉点v的道路。Bertown中的所有道路都是成对的,这意味着每个有序对(u,v)在这m行中最多出现一次(但如果有道路(u,v),则道路(v,u)也会出现)。

下一行包含一个整数k(2≤k≤n)-Polycarp从家到工作场所的路径中的交点数。

最后一行包含k个整数p1,p2,...,pk(1≤pi≤n,所有这些整数都是成对截然不同的)-沿Polycarp路径的交点,以他到达它们的顺序。 p1是Polycarp居住的路口(s = p1),而pk是Polycarp工作场所所在的路口(t = pk)。保证对于每一个i∈[1,k-1]都存在从pi到pi + 1的道路,因此该路径沿着Bertown的道路行进。

输出量 打印两个整数:在旅途中可能发生的最小和最大重建次数。

Codeforces补题2020.3.2 (Round625 Div2)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+14;
vector<int> g[maxn];
int d[maxn];
int p[maxn];
queue<int> q;
unordered_set<int> st[maxn];
void bfs (int s) {
    memset(d,-1,sizeof(d));
    d[s]=0;
    q.push(s);
    while (!q.empty()) {
        int u=q.front();
        q.pop();
        for (int i=0;i<g[u].size();i++) {
            if (d[g[u][i]]==-1||d[g[u][i]]==d[u]+1) 
                st[g[u][i]].insert(u);
            if (d[g[u][i]]==-1) {
                d[g[u][i]]=d[u]+1;
                q.push(g[u][i]);
            }
        }
    }
}
int main () {
    int N,M,u,v;
    int K;
    int ans1,ans2;
    scanf("%d %d",&N,&M);
    for (int i=0;i<M;i++) {
        scanf("%d%d",&u,&v);
        g[v].push_back(u);
    }
    scanf("%d",&K);
    for (int i=0;i<K;i++) 
        scanf("%d",&p[i]);
    bfs(p[K-1]);
    ans1=0;
    ans2=0;
    for (int i=0;i<K-1;i++) {
        if (st[p[i]].count(p[i+1])&&st[p[i]].size()>1) 
            ans2++;
        else if (!st[p[i]].count(p[i+1])) {
            ans1++;
            ans2++; 
        }
    }
    printf ("%d %d\n",ans1,ans2);
    return 0;
}
View Code

 

上一篇:Codeforces Round #625 (Div. 2) A ~ D


下一篇:java写的贪吃蛇小游戏