2020, XIII Samara Regional Intercollegiate Programming Contest (B D)

B - Bonuses on a Line

Practice link:https://vjudge.net/contest/392621#problem/B


题意:数轴上有n个点,每个点的位置为({}_{x_{i}}) ,你有t单位的移动距离,问你在你的移动距离内最多可以经过几个点。
思路:首先把正点和负点分开储存,然后枚举经过负点的个数,可以得到此时消耗掉的移动距离,再用二分查找可以经过正点的最大数目。
代码:

‘’‘’‘’
vector<int>v1,v2;
int main()
{
    int n,t;
    scanf("%d %d",&n,&t);
    int p1=0,p2=0;
    for(int i=1;i<=n;i++){
        int num;
        scanf("%d",&num);
        if(num>=0){
            v2.push_back(num);
        }else{
            v1.push_back(abs(num));
        }
    }
    sort(v1.begin(),v1.end());
    sort(v2.begin(),v2.end());
    p1=v1.size();
    p2=v2.size();
    int maxn=0,kk=t,num;
    for(int i=0;i<p1;i++){
        kk=t;
        num=i+1;
        if(v1[i]>t)break;
        kk-=2*v1[i];
        int upp=upper_bound(v2.begin(),v2.end() ,kk)-v2.begin();
        num+=upp;
        maxn=max(maxn,num);
    }
    for(int i=0;i<p2;i++){
        kk=t;
        num=i+1;
        if(v2[i]>t)break;
        kk-=2*v2[i];
        int upp=upper_bound(v1.begin(),v1.end() ,kk)-v1.begin();
        num+=upp;
        maxn=max(maxn,num);
    }
    printf("%d
",maxn);
    return 0;
}

D - Lexicographically Minimal Shortest Path

Practice link:https://vjudge.net/contest/392621#problem/D


题意:给你n个点,m条边的无向图,每条边都有一个字母,问你从 1 ~ n 的字典序最小的最短路。
思路:首先就是这是无权边,我们可以通过一次bfs求出每个点到 n 的最短距离,储存在dis数组中。然后我们从节点1开始,去寻找节点1的后继节点且到节点n距离为 当前节点到节点n的距离-1 的点,然后去比较其中边的字典序,去求最小的字典序,如果遇到有多个最小字典序,则把这些点都放入vector,否则vector只放字典序最小边的连点,然后在下一步继续进行这个循环,直到到达 n 点。
代码:

‘’‘’‘’
const int MAXN = 200005 ;
vector<pair<int,char>>vv[MAXN];
int n,m;
int dis[MAXN];
int fa[MAXN];
int main()
{
    mem(dis,0);
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++){
        int u,v;
        char c;
        scanf("%d %d %c",&u,&v,&c);
        vv[u].push_back(make_pair(v,c));
        vv[v].push_back(make_pair(u,c));
    }
    mem(dis,-1);
    mem(fa,-1);
    dis[n]=0;
    queue<int>q;
    q.push(n);
    while(!q.empty()){
        int top=q.front();
        q.pop();
        for(auto i:vv[top]){
            int to=i.first;
            if(dis[to]==-1){
                dis[to]=dis[top]+1;
                q.push(to);
            }
        }
    }
    string ans;
    vector<int>temp;
    temp.push_back(1);
    for(int i=0;i<dis[1];i++){
        char minc='z'+1;
        vector<int>nxt;
        for(auto j:temp){
            for(auto k:vv[j]){
                if(dis[k.first]==dis[j]-1){
                    if(k.second<minc){
                        minc=k.second;
                        nxt.clear();
                        nxt.push_back(k.first);
                        fa[k.first]=j;
                    }else if(k.second==minc){
                        nxt.push_back(k.first);
                        fa[k.first]=j;
                    }
                }
            }
        }
        sort(nxt.begin(),nxt.end());
        nxt.erase(unique(nxt.begin(),nxt.end()),nxt.end());
        temp=nxt;
        ans+=minc;
    }
    vector<int>path;
    int pa=n;
    while(pa!=-1){
       path.push_back(pa);
       pa=fa[pa];
    }
    reverse(path.begin(),path.end());
    printf("%d
",path.size()-1);
    for(auto i:path){
        cout<<i<<" ";
    }
    printf("
");
    cout<<ans;
    return 0;
} 
越自律,越自由
原文地址:https://www.cnblogs.com/ha-chuochuo/p/13614614.html