• Codeforces Round #101 (Div. 2)


    --------------

    A. Amusing Joke

    --

    前两行的字母恰好组成最后一行

    --

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    char a[1111];
    int ch[26]={0};
    
    int main()
    {
        cin>>a;
        for (int i=0;a[i];i++){
            ch[a[i]-'A']++;
        }
        cin>>a;
        for (int i=0;a[i];i++){
            ch[a[i]-'A']++;
        }
        cin>>a;
        for (int i=0;a[i];i++){
            ch[a[i]-'A']--;
        }
        bool flag=true;
        for (int i=0;i<26;i++){
            if (ch[i]!=0){
                cout<<"NO"<<endl;
                flag=false;
                break;
            }
        }
        if (flag) cout<<"YES"<<endl;
        return 0;
    }
    -------------

    B. Hopscotch

    ----

    模拟计算(x,y)所在的格子
    公式易推,注意边界

    ----

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    void solve(int a,int x,int y){
        if (y%a==0){
            cout<<-1<<endl;
            return;
        }
        int fl=y/a;
        if (fl==0){
            if (2*x<a&&2*x>-a) cout<<1<<endl;
            else cout<<-1<<endl;
            return;
        }
        int nu=(fl+1)/2;
        if (fl%2==1){
            if (2*x<a&&2*x>-a) cout<<nu*3-1<<endl;
            else cout<<-1<<endl;
            return;
        }
        else{
            if (x>0&&x<a) cout<<nu*3+1<<endl;
            else if (x<0&&x>-a) cout<<nu*3<<endl;
            else cout<<-1<<endl;
            return;
        }
    }
    
    int main()
    {
        int a,x,y;
        cin>>a>>x>>y;
        solve(a,x,y);
        return 0;
    }

    --------------

    C. Queue

    ---

    有n个人排成一队

    给出每个人前面比他高的人数

    构造一个身高序列

    ---

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int INF=0x3f3f3f;
    const int MAXN=10000;
    struct Data{
        string name;
        int a;
        int h;
    }f[MAXN];
    bool cmp(Data x,Data y){
        return x.a<y.a;
    }
    int n,m;
    int main()
    {
        cin>>n;
        for (int i=0;i<n;i++){
            cin>>f[i].name>>f[i].a;
        }
        sort(f,f+n,cmp);
        for (int i=0;i<n;i++){
            if (f[i].a>i){
                cout<<-1<<endl;
                return 0;
            }
        }
        m=0;
        for (int i=0;i<n;i++){
            f[i].h=i+1-f[i].a;
            for (int j=0;j<i;j++){
                if (f[j].h>=f[i].h) f[j].h++;
            }
    
        }
        for (int i=0;i<n;i++){
            cout<<f[i].name<<" "<<f[i].h<<endl;
        }
        return 0;
    }

    --------------

    D. Take-off Ramps

    ----

    长度为L的场地里有n个跳板

    对位于坐标Xi的跳板,要提前Pi米准备,跳到Di用时Ti。

    问从0到L的最短距离。

    ----

    以0、L、Xi-Pi、Xi+Di为顶点构造图。

    从0到L的最短路即为所求。

    将每个顶点按坐标排序,相邻两个顶点之间建一条长度为两点距离差绝对值的边

    跳板两端点间建一条长度为Pi+Ti的边。

    距离有可能超过int。

    注意输出格式以及时间效率。

    --------------

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <map>
    #include <cstdio>
    using namespace std;
    typedef long long LL;
    const long long INF=1LL << 60;
    const int maxn=500000;
    const int maxm=5000000;
    struct EdgeNode{
        int to;
        LL w;
        int next;
    };/*==============================================*
     | Dijkstra+堆优化
     | INIT: init(n);addedge(u,v,c);节点编号0~n
     | CALL: dijkstra(int s);dis[]:最短路;pre[]:前驱
    *==============================================*/
    struct HeapNode{
        LL d;
        int u;
        HeapNode(){}
        HeapNode(LL a,int b):d(a),u(b){}
        bool operator<(const HeapNode& rhs) const{
            return d>rhs.d;
        }
    };
    struct Dijkstra{
        EdgeNode edges[maxm];
        int head[maxn];
        int edge,n;
        void init(int n){
            this->n=n;
            memset(head,-1,sizeof(head));
            edge=0;
        }
        void addedge(int u,int v,LL c){
            edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
        }
        bool done[maxn];
        LL dis[maxn];
        int pre[maxn];
        void dijkstra(int s){
            priority_queue<HeapNode>que;
            for (int i=0;i<=n;i++) dis[i]=INF;
            dis[s]=0;
            memset(done,0,sizeof(done));
            que.push(HeapNode(0,s));
            while (!que.empty()){
                HeapNode x=que.top();
                que.pop();
                int u=x.u;
                if (done[u]) continue;
                done[u]=true;
                for (int i=head[u];i!=-1;i=edges[i].next){
                    int v=edges[i].to;
                    LL w=edges[i].w;
                    if (dis[v]>dis[u]+w){
                        dis[v]=dis[u]+w;
                        pre[v]=u;
                        que.push(HeapNode(dis[v],v));
                    }
                }
            }
        }
    }G;
    struct Data{
        int x,d,t,p;
        int id;
    }a[maxn];
    struct POI{
        int p;
        int id;
        POI(){}
        POI(int a,int b):p(a),id(b){}
    };
    vector<POI>vec;
    bool cmp(POI a,POI b){
        return a.p<b.p;
    }
    vector<int>ans;
    int mp[maxn];
    int main()
    {
        int n,L,m;
        memset(mp,-1,sizeof(mp));
        scanf("%d%d",&n,&L);
        G.init(2*n+1);
        m=0;
        for (int i=1;i<=n;i++){
            scanf("%d%d%d%d",&a[i].x,&a[i].d,&a[i].t,&a[i].p);
            a[i].id=i;
            G.addedge(i,i+n,a[i].p+a[i].t);
            if (a[i].t<a[i].d){
                mp[i+n]=i;
            }
            //cerr<<i<<" "<<i+n<<" "<<a[i].t<<endl;
            vec.push_back(POI(a[i].x-a[i].p,i));
            vec.push_back(POI(a[i].x+a[i].d,i+n));
        }
        vec.push_back(POI(L,2*n+1));
        vec.push_back(POI(0,0));
        sort(vec.begin(),vec.end(),cmp);
        for (int i=0;i<(int)vec.size()-1;i++){
            if (vec[i].p<0) continue;
            G.addedge(vec[i].id,vec[i+1].id,abs(vec[i+1].p-vec[i].p));
            G.addedge(vec[i+1].id,vec[i].id,abs(vec[i].p-vec[i+1].p));
            //cerr<<vec[i].id<<" "<<vec[i+1].id<<" "<<abs(vec[i+1].p-vec[i].p)<<endl;
        }
        G.dijkstra(0);
        printf("%I64d
    ",G.dis[2*n+1]);
        int t=2*n+1;
        while (t!=0){
            if (mp[t]==G.pre[t]) ans.push_back(G.pre[t]);
            t=G.pre[t];
        }
        printf("%d
    ",ans.size());
        for (int i=(int)ans.size()-1;i>=0;i--){
            printf("%d ",ans[i]);
        }
        printf("
    ");
        return 0;
    }

    -------------

    E. Clearing Up

    --------

    有n个节点的图,求最小生成树,要求S与M各占一半。

    ---------

    易知最小生成树有n-1条边,一半为S一半为M

    定义两个并查集S1、S2。答案集e1,e2。

    保证属于一个集合的顶点中,任意两个顶点之间有且只有一条简单路径。

    首先只考虑S边,将S边相连的顶点合并到并查集S1里的一个集合

    考虑M边,若最终想要得到一个最小生成树,则并查集S1中必须只有一个集合。

    所以枚举所有M边,若某M边能连接S1中不同集合的顶点,则在S1、S2中合并这两个顶点,将该M边加入答案集e1。

    如果此时M边不满(n-1)/2,枚举M边,若该边能连接S2中的不同集合则合并这两个集合并将该M边加入答案集e1。

    枚举所有S边,若能连接S2中不集合则合并集合并将该S边加入答案集e2。

    最终答案集e1中储存的是最小生成树中的M边,e2为S边。并且size(e1)=(n-1)/2。

    若size(e1)!=size(e2)则无解。

    ---------

    #include <iostream>
    #include <vector>
    #include <cstring>
    #define sz(x) int(x.size())
    using namespace std;
    const int maxn=11111;
    const int maxm=111111;
    struct DisjointSet{
        int pa[maxn];
        void makeSet(int n){
            for (int i=0;i<=n;i++) pa[i]=i;
        }
        int findSet(int x){
            if (x!=pa[x]) pa[x]=findSet(pa[x]);
            return pa[x];
        }
        void unionSet(int x,int y){
            x=findSet(x);
            y=findSet(y);
            if (x!=y) pa[x]=y;
        }
    }s1,s2;
    
    int n,m;
    struct Edge{
        int u,v;
        char c;
    };
    Edge vec[maxm];
    vector<int> e1,e2;
    int d;
    int main()
    {
        cin>>n>>m;
        for (int i=0;i<m;i++){
            cin>>vec[i].u>>vec[i].v>>vec[i].c;
        }
        s1.makeSet(n);
        s2.makeSet(n);
        for (int i=0;i<m;i++){
            if (vec[i].c=='S'){
                if (s1.findSet(vec[i].u)!=s1.findSet(vec[i].v)){
                    s1.unionSet(vec[i].u,vec[i].v);
                }
            }
        }
        d=(n-1)/2;
        for (int i=0;i<m;i++){
            if (vec[i].c=='M'){
                if (s1.findSet(vec[i].u)!=s1.findSet(vec[i].v)){
                    s1.unionSet(vec[i].u,vec[i].v);
                    s2.unionSet(vec[i].u,vec[i].v);
                    e1.push_back(i);
                    d--;
                }
            }
        }
        for (int i=0;i<m;i++){
            if (vec[i].c=='M'&&d>0){
                if (s2.findSet(vec[i].u)!=s2.findSet(vec[i].v)){
                    s2.unionSet(vec[i].u,vec[i].v);
                    e1.push_back(i);
                    d--;
                }
            }
        }
        for (int i=0;i<m;i++){
            if (vec[i].c=='S'){
                if (s2.findSet(vec[i].u)!=s2.findSet(vec[i].v)){
                    s2.unionSet(vec[i].u,vec[i].v);
                    e2.push_back(i);
                }
            }
        }
        d=(n-1)/2;
        if (sz(e1)!=d||sz(e2)!=d) cout<<-1<<endl;
        else{
            cout<<n-1<<endl;
            for (int i=0;i<sz(e1);i++){
                cout<<e1[i]+1<<" ";
            }
            for (int i=0;i<sz(e2);i++){
                cout<<e2[i]+1<<" ";
            }
            cout<<endl;
        }
        return 0;
    }
    


    ---------

    -

  • 相关阅读:
    DBHelper
    ASP.NET WEBAPI oken验证
    市面上的网盘和搜索网盘资源网站
    C#批量删除注释与空行
    DB help
    抽象工厂1
    抽象工厂
    单例模式的八种写法
    Docker概念
    Django的安装
  • 原文地址:https://www.cnblogs.com/cyendra/p/3681640.html
Copyright © 2020-2023  润新知