Codeforces Round #625 (Div. 2, based on Technocup 2020 Final Round)

A. Contest for Robots

题目大意:
有a,b两家公司,n个问题,给出每家公司可以解决哪些问题。构造出所有问题的分数使得a公司比b公司得分高的前提下,求出单个问题最高分最小的可能是多少。
思路:
贪心。对于两家都答对的问题不用考虑,b公司答对而a公司每答对的问题为1分共得x分,设a公司答对x+1分答对y个问题,那么最高分的问题就是\((x+1)/y+((x+1)\%y==0?0:1)\)

#include<bits/stdc++.h>
using namespace std;
int a[110],b[110];
int main(){
    int n;
    cin>>n;
    int sa=0,sb=0;
    for(int i=1;i<=n;++i)
        cin>>a[i];
    for(int i=1;i<=n;++i){
        cin>>b[i];
        if(b[i]==1&&a[i]==0){
            sb+=1;
        }
        else if(b[i]!=1&&a[i]==1){
            sa+=1;
        }
    }
    if(sa==0){
        cout<<"-1";
    }
    else if(sa>sb){
        cout<<"1";
    }
    else {
        int t=(sb+1)/sa+((sb+1)%sa==0?0:1);
        cout<<t;
    }
    return 0;
}

B. Journey Planning

题目大意:
给出两个序列a_1,a_2,...,a_n。构造出一个子序列\(a_i,a_j,a_k,...,a_t\) ,对于每个元素都有:\(a[j]-a[i]=j-i\) (\(i<\)j,并且a_i,a_j在子序列相邻)

思路:
\(a[j]-a[i]=j-i\)可得\(a[j]-j=a[i]-i\),可以发现对于可以组合在一个子序列里的所有元素的值和下标之差相等。

#include<bits/stdc++.h>
using namespace std;
map<int,long long> sub;
int main(){
    int n,x;
    cin>>n;
    for(int i=1;i<=n;++i){
        cin>>x;
        sub[x-i]+=x;
    }
    long long res=0;
    for(int i=-400010;i<=400010;++i){
        if(sub.count(i))
            res=max(sub[i],res);
    }
    cout<<res<<'\n';
    return 0;
}

C. Remove Adjacent

题目大意:
给出一个字符串,串内可以被删除的字母前提为,存在一个与该字母相邻(左或右)的字母是它字典序的前一个字母,例如abc,b可受a的影响被删除,c可受b的影响被删除。求最多可删除多少个字母。( \(N<100\) )
思路:
可以这样想,在最优方案中一个字母在满足删除条件下时被当即删除的前提是它是当前所有满足条件中的中最大的字母,即它不能影响到其他字母的可能性最小,删除它可能会产生更多可能。(好吧,感觉不是很严谨,其实我是猜出来这样贪心的)
代码:
https://paste.ubuntu.com/p/cNtvJKjCWn/

D. Navigation System

题目大意:
在有向图中按照一个固定的路线开车从s到t,车上有一个导航,导航可以给出从每个点到t的最短路线。每到一个点,导航会根据该点是否是根据推荐路线到达的,如果不是就会给出从当前点到t的新的最短路线。求导航最少和最多会给出多少次新路线(因为一个点到t的最短路可能不止一条)。
思路:
需要所有反向建图跑spfa,求每个点到t的最短路。
导航给出新路线有两种可能,假设从u->v :
1' u到t的最短距离\(d[u]-1<d[v]\),即u->v不在u到t的任意一条最短路上。
2' \(d[u]-1==d[v]\),但u到t有不包含v的最短路,即导航可能推荐出了另一条最短路线。

#include<bits/stdc++.h>
using namespace std;
 
const int N=2e5+10;
 
vector<int> g1[N],g2[N];
int p[N],dis[N],inq[N],k;
queue<int> q;
 
void spfa(){
    memset(dis,0x3f,sizeof dis);
    memset(inq,0,sizeof inq);
    q=queue<int>();
    dis[p[k]]=0;
    q.push(p[k]);
    inq[p[k]]=1;
    while(!q.empty()){
        int u=q.front();
        q.pop();
        inq[u]=0;
        for(int i=0,v;i<g2[u].size();++i){
            v=g2[u][i];
            if(dis[v]>dis[u]+1){
                dis[v]=dis[u]+1;
                if(!inq[v]){
                    q.push(v);
                    inq[v]=1;
                }
            }
        }
    }
}
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1,u,v;i<=m;++i){
        cin>>u>>v;
        g1[u].push_back(v);
        g2[v].push_back(u);
    }
    cin>>k;
    for(int i=1;i<=k;++i)
        cin>>p[i];
    spfa();
    int Min=0,Max=0;
    for(int i=1,u,v;i<k;++i){
        u=p[i],v=p[i+1];
        if(dis[v]!=dis[u]-1) ++Min,++Max;
        else {
            for(int i=0,v2;i<g1[u].size();++i){
                v2=g1[u][i];
                if(dis[v2]==dis[v]&&v!=v2) {
                    ++Max;
                    break;
                }
            }
        }
    }
    cout<<Min<<" "<<Max<<'\n';
    return 0;
}
posted @ 2020-03-18 14:33  0x4f  阅读(107)  评论(0编辑  收藏  举报