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\n");
        }else{
            printf("NO\n");
        }
    }   
}
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\n",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\n");
            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\n");
            for(int i=1;i<=m;i++){
                printf("%d%c",ans[i]," \n"[i==m]);
            }
        }else{
            printf("NO\n");
        }
    }
}
D、AB Graph
题意:

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

想法:

  • 分类讨论。
  • 1、m为奇数,可以发现如 \(ababa\)\(aaaaa\) 都是回文,且边权只有可能是 \(a,b\),那么只需要在 \(1\) 号点和 \(2\) 号点之间不断走即可。
  • 2、m为偶数,图上存在两点之间两条边权相同,那么只要这两条边之间相互走即可。
  • 3、除去以上两种情况,我们考虑是否可以有三个点去构造,发现这样子三个点就可以,三元组 \(<x,y,z>\) 满足 \((x\rightarrow y)\) = \((y\rightarrow z)\),因为这个情况下已经除去上面两种情况,那么 \((z\rightarrow y)\) = \((y\rightarrow x)\)一定成立。
  • \(x\rightarrow y = b\)。那么 \(y\rightarrow z = b\)\(z\rightarrow y = a\)\(y\rightarrow x = a\)
  • 然后对于回文串长度的一半是偶数,那么 \(ababbaba\) 显然是满足的,那么对于前一半 \(abab\),从 \(y\) 开始,和 \(x\) 不断循环即可,后一半 \(baba\)\(y\)\(z\) 之间走即可。
  • 对于回文串长度的一半是奇数,那么 \(abababa\)显然满足。对于前一半 \(aba\) ,从 \(x\) 开始,和 \(y\)不断循环,那么最后来到 \(y\) 点,然后 \(y\rightarrow 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]," \n"[i==m+1]);
            }
            continue;
        }
        if(m%2==1){
            printf("YES\n");
            for(int i=1;i<=m+1;i++){
                printf("%c%c","12"[i%2==0]," \n"[i==m+1]);
            }
            continue;
        }else{
            if(n==2){
                printf("NO\n");
                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\n");
                continue;
            }
            printf("YES\n");
            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("\n");
        }
    }   
    return 0;
}
posted @ 2021-02-07 21:23  hachuochuo  阅读(100)  评论(0编辑  收藏  举报