zoukankan      html  css  js  c++  java
  • Codeforces Round #699 (Div. 2)(A,B,C,D)

    Solved


    Solutions


    A、Space Navigation
    water. 代码:
    string s;
    map<char,int>mp;
    int main()
    {
        int T;
        cin>>T;
        while(T--){
            int x,y;
            mp.clear();
            mp['U']=0;
            mp['R']=0;
            mp['D']=0;
            mp['L']=0;
            cin>>x>>y;
            cin>>s;
            for(int i=0;i<s.size();i++){
                mp[s[i]]++;
            }
            if((x>=0&&y>=0&&mp['R']>=x&&mp['U']>=y)||(x>=0&&y<0&&mp['R']>=x&&mp['D']>=abs(y))||(x<0&&y>=0&&mp['L']>=abs(x)&&mp['U']>=y)||(x<0&&y<0&&mp['L']>=abs(x)&&mp['D']>=abs(y))){
                printf("YES
    ");
            }else{
                printf("NO
    ");
            }
        }   
    }
    
    B、New Colony

    题意:

    (n) 座山,高度为 (h[i]) ,从起点开始一个个丢桶,遇到 (h[i-1]<h[i]) 的情况,则该桶停留在第 (i-1) 座山中,并且 (h[i-1]=h[i-1]+1),问你第 (k) 个桶在哪座山中(桶有可能直接到达终点,则输出 (-1))。

    想法:

    (h[i]) 数据范围小,我们直接暴力模拟放桶的过程即可。

    代码:

    int h[205];
    int main()
    {
        int T;
        int n,k;
        cin>>T;
        while(T--){
            cin>>n>>k;
            int now=0;
            for(int i=1;i<=n;i++){
                scanf("%d",&h[i]);
                
            }
            int sum=0;
            int pos=-1;
            int xx;
            while(sum<k){
                xx=1;
                //cout<<sum<<endl;
                for(int j=2;j<=n;j++){
                    if(h[j]>h[j-1]){
                        pos=j-1;
                        sum++;
                        h[j-1]++;
                        xx=0;
                        break;
                    }
                    //if(sum>=k)break;
                }
                //cout<<pos<<" "<<sum<<endl;
                if(xx==1)break;
            }
            if(sum<k)pos=-1;
            printf("%d
    ",pos);
        }   
    }
    
    C、Fence Painting

    题意:

    (n) 面墙,最初颜色为 (a[i]) ,题目期望颜色为 (b[i])。有 (m) 个画家,每个画家按给定顺序给某面墙画上颜色 (c[i]),颜色可以覆盖,但每个画家必须画一面墙。问是否有可能使每面墙都达到期望颜色。

    想法:

    • 首先我们看到画家有出场顺序,那么我们最需要考虑的是顺序后面的画家,因为后面的画家一定会对墙造成影响,而前面画家的影响可能会被后面的覆盖。
    • 考虑第一种情况,期望颜色和初始颜色相同,只需要看最后出场的画家的颜色是否存在,若存在就在相同颜色的墙山画,前面的画家也在这面墙上画即可。否则就是 (NO)
    • 第二种情况,期望颜色和初始颜色不相同,那么我们把不相同的画的颜色和各个颜色的数量存储起来。对每个画家进行遍历,从后往前遍历,遇到该画家画的颜色是被需要的,则画在需要的墙上,否则画在这个画家后面的画家要画的墙上,因为这样子这个多余的颜色的影响就会被后面的画家的影响覆盖。
    • 最后遍历所有墙,看是否符合即可。

    代码:

    int a[maxn],b[maxn];
    int c[maxn];
    int ans[maxn];
    struct node{
        int id;
        int co;
    };
    vector<int>v[maxn];
    vector<int>vv;
    int num[maxn];
    int num2[maxn];
    int poss[maxn];
    int main()
    {
        int T,n,m;
        cin>>T;
        while(T--){
            vv.clear();
            cin>>n>>m;
            mem(poss,-1);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                num[i]=0;
                num2[i]=0;
                v[i].clear();
            }
            for(int i=1;i<=n;i++){
                scanf("%d",&b[i]);
                poss[b[i]]=i;
                num2[b[i]]++;
            }
            for(int i=1;i<=m;i++){
                scanf("%d",&c[i]);
            }
            for(int i=1;i<=n;i++){
                if(a[i]!=b[i]){
                    v[b[i]].push_back(i);
                    vv.push_back(b[i]);
                    num[b[i]]++;
                }
            }
            if(vv.size()>m){
                printf("NO
    ");
                continue;
            }
            if(vv.size()>0)sort(vv.begin(),vv.end());
            int siz=vv.size();
            int k=1;
            int sumn=0;
            vector<int>have;
            if(vv.size()>0){
                for(int i=m;i>=1;i--){
                    //int pos=lower_bound(vv.begin(),vv.end(),c[i])-vv.begin();
                    //cout<<vv[pos]<<" "<<pos<<endl;
                    if(v[c[i]].size()<=0){
                        if(have.size()){
                            ans[i]=have[0];
                        }else if(num2[c[i]]){
                            ans[i]=poss[c[i]];
                            have.push_back(poss[c[i]]);
                        }else{
                            k=0;
                            break;
                        }
                    }else{
                        int nowsize=v[c[i]].size();
                        int xx=v[c[i]][nowsize-1];
                        have.push_back(xx);
                        ans[i]=xx;
                        v[c[i]].pop_back();
                        sumn++;
                    }
                }
            }else{
                if(poss[c[m]]!=-1){
                    for(int i=1;i<=m;i++)ans[i]=poss[c[m]];
                }else{
                    k=0;
                }
            }
            if(sumn<vv.size())k=0;
            /*
            for(int i=1;i<=m;i++){
                cout<<ans[i]<<" ";
            }
            cout<<endl;
            */
            if(k){
                printf("YES
    ");
                for(int i=1;i<=m;i++){
                    printf("%d%c",ans[i]," 
    "[i==m]);
                }
            }else{
                printf("NO
    ");
            }
        }
    }
    
    D、AB Graph
    题意:

    给你一幅 (n) 个点的完全图,这幅图的边权只有可能是 (a)(b) 。问你能否在这幅图上找到长度为 (m) 的路径,使路径上的字母按顺序构成一个回文串(每个点和每条边可以经过多次)。

    想法:

    • 分类讨论。
    • 1、m为奇数,可以发现如 (ababa)(aaaaa) 都是回文,且边权只有可能是 (a,b),那么只需要在 (1) 号点和 (2) 号点之间不断走即可。
    • 2、m为偶数,图上存在两点之间两条边权相同,那么只要这两条边之间相互走即可。
    • 3、除去以上两种情况,我们考虑是否可以有三个点去构造,发现这样子三个点就可以,三元组 (<x,y,z>) 满足 ((x ightarrow y)) = ((y ightarrow z)),因为这个情况下已经除去上面两种情况,那么 ((z ightarrow y)) = ((y ightarrow x))一定成立。
    • (x ightarrow y = b)。那么 (y ightarrow z = b)(z ightarrow y = a)(y ightarrow x = a)
    • 然后对于回文串长度的一半是偶数,那么 (ababbaba) 显然是满足的,那么对于前一半 (abab),从 (y) 开始,和 (x) 不断循环即可,后一半 (baba)(y)(z) 之间走即可。
    • 对于回文串长度的一半是奇数,那么 (abababa)显然满足。对于前一半 (aba) ,从 (x) 开始,和 (y)不断循环,那么最后来到 (y) 点,然后 (y ightarrow z) 得到中间的 (b),后一半 (aba) ,从 (z) 开始和 (y) 不断循环即可。

    代码:

    int n,m;
    char mp[maxn][maxn];
    int ans[maxn][3];
    int main()
    {
        int T;
        cin>>T;
        while(T--){
            cin>>n>>m;
            for(int i=1;i<=n;i++){
                ans[i][1]=-1;
                ans[i][2]=-1;
            };
            for(int i=1;i<=n;i++){
                getchar();
                for(int j=1;j<=n;j++){
                    scanf("%c",&mp[i][j]);
                    if(i!=j)ans[i][mp[i][j]-'a'+1]=j;
                }
            }
            int k1=0;
            int kk[3];
            for(int i=1;i<=n;i++){
                for(int j=1;j<i;j++){
                    if(mp[i][j]==mp[j][i]){
                        kk[1]=i;
                        kk[2]=j;
                        k1=1;
                        break;
                    }
                }
                if(k1)break;
            }
            if(k1){
                cout<<"YES"<<endl;
                for(int i=1;i<=m+1;i++){
                    printf("%d%c",kk[i%2+1]," 
    "[i==m+1]);
                }
                continue;
            }
            if(m%2==1){
                printf("YES
    ");
                for(int i=1;i<=m+1;i++){
                    printf("%c%c","12"[i%2==0]," 
    "[i==m+1]);
                }
                continue;
            }else{
                if(n==2){
                    printf("NO
    ");
                    continue;
                }
                int x,y,z;
                int ok=0;
                for(int i=1;i<=n;i++){
                    for(int j=1;j<=n;j++){
                        if(i==j)continue;
                        if(ans[j][mp[i][j]-'a'+1]!=-1){
                            x=i;
                            y=j;
                            z=ans[j][mp[i][j]-'a'+1];
                            ok=1;
                            goto end;
                        }
                    }
                }
                end:;
                if(!ok){
                    printf("NO
    ");
                    continue;
                }
                printf("YES
    ");
                if((m/2)%2==0){
                    printf("%d",y);
                    for(int i=1;i<=m/2;i++){
                        if(i%2==1){
                            printf(" %d",x);
                        }else{
                            printf(" %d",y);
                        }
                    }
                    for(int i=1;i<=m/2;i++){
                        if(i%2==1){
                            printf(" %d",z);
                        }else{
                            printf(" %d",y);
                        }
                    }
                }else{
                    printf("%d",x);
                    for(int i=1;i<=m/2;i++){
                        if(i%2==1){
                            printf(" %d",y);
                        }else{
                            printf(" %d",x);
                        }
                    }
                    for(int i=1;i<=m/2;i++){
                        if(i%2==1){
                            printf(" %d",z);
                        }else{
                            printf(" %d",y);
                        }
                    }
                }
                printf("
    ");
            }
        }   
        return 0;
    }
    
    越自律,越自由
  • 相关阅读:
    P1829 [国家集训队]Crash的数字表格 / JZPTAB 莫比乌斯反演
    Luogu P1447 [NOI2010]能量采集 数论??欧拉
    Luogu P2522 [HAOI2011]Problem b 莫比乌斯反演
    Luogu P2257 YY的GCD 莫比乌斯反演
    [笔记] 数论函数小记
    [笔记] 线性筛小记
    Luogu P1092 虫食算 爆搜
    Luogu P1066 2^k进制数 组合数学
    Luogu P1641 [SCOI2010]生成字符串 组合数学
    Luogu P2532 [AHOI2012]树屋阶梯 卡特兰数
  • 原文地址:https://www.cnblogs.com/ha-chuochuo/p/14386726.html
Copyright © 2011-2022 走看看