zoukankan      html  css  js  c++  java
  • 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;
    }
    


    ---------

    -

  • 相关阅读:
    leetcode 78. 子集 JAVA
    leetcode 91. 解码方法 JAVA
    leetcode 75. 颜色分类 JAVA
    leetcode 74 搜索二维矩阵 java
    leetcode 84. 柱状图中最大的矩形 JAVA
    last occurance
    first occurance
    classical binary search
    LC.234.Palindrome Linked List
    LC.142. Linked List Cycle II
  • 原文地址:https://www.cnblogs.com/cyendra/p/3681640.html
Copyright © 2011-2022 走看看