码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #663 (Div. 2)训练小结

时间:2020-10-08 19:22:44      阅读:15      评论:0      收藏:0      [点我收藏+]

标签:codeforce   names   步骤   排列   ret   long   using   div   base   

链接

Virtual participation

A. Suborrays

观察发现任何排列均满足题意。

#include<bits/stdc++.h>
using namespace std;
int N;
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T;cin>>T;
    while(T--){
        cin>>N;
        for(int i=1;i<=N;++i)
            printf("%d ",i);
        puts("");
    }
    return 0;
}

B. Fix You

由于要求从任意位置都能走到右下角,只要让最后一行均为“R”,最后一列均为“D”即可。可以证明这是最优解。

#include<bits/stdc++.h>
using namespace std;
int N,M,ans;
char A[110][110];
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T;cin>>T;
    while(T--){
        ans=0;
        cin>>N>>M;
        for(int i=1;i<=N;++i)
            cin>>A[i]+1;
        for(int i=1;i<N;++i)
            if(A[i][M]!=‘D‘)
                ++ans;
        for(int j=1;j<M;++j)
            if(A[N][j]!=‘R‘)
                ++ans;
        printf("%d\n",ans);
    }
    return 0;
}

C. Cyclic Permutations

组合数学。

观察发现,只有最大数的左侧升序,右侧降序的排列符合题意。

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int N,fac[1000010],ifac[1000010];
long long ans;
int C(int n,int m){
    if(n<m)return 0;
    return 1ll*fac[n]*ifac[m]%mod*ifac[n-m]%mod;
}
int qpow(int base,int b){
    int res=1;
    while(b){
        if(b&1)res=1ll*res*base%mod;
        base=1ll*base*base%mod;
        b>>=1;
    }
    return res;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>N;
    fac[0]=1;
    for(int i=1;i<=N;++i)
        fac[i]=1ll*fac[i-1]*i%mod;
    ifac[N]=qpow(fac[N],mod-2);
    for(int i=N;i>=1;--i)
        ifac[i-1]=1ll*ifac[i]*i%mod;
    ans=fac[N];
    for(int i=1;i<=N;++i)
        ans=(ans-C(N-1,i-1)+mod)%mod;
    printf("%lld\n",ans);
    return 0;
}

D. 505

状压DP。

\(N\ge 4\)\(M\ge 4\) 时,不存在解。所以行/列不超过3,且只需要考虑 \(2\times 2\) 的子矩阵即可。显然可以状压DP。

\(f(i,S)\) 表示“做到第 \(i\) 行(列),当前行(列)的01序列为 \(S\) ”的最少步骤数。

#include<bits/stdc++.h>
using namespace std;
int N,M,A[1000010],B[5],ans;
int F[1000010][10];
char str[1000010];
int getPos(int x,int y){
    return x*M+y;
}
int isRight(int k1,int k2,int x){
    memset(B,0,sizeof(B));
    for(int i=0;i<x;++i,k1>>=1,k2>>=1)
        B[i]=(k1&1)+(k2&1);
    for(int i=1;i<x;++i)
        if((B[i-1]+B[i])%2==0)
            return 0;
    return 1;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>N>>M;ans=1e6;
    for(int i=0;i<N;++i){
        cin>>str;
        for(int j=0;j<M;++j)
            A[getPos(i,j)]=str[j]-‘0‘;
    }
    if(N>=4&&M>=4)puts("-1");
    else{
        int tmp;
        if(N<2||M<2)puts("0");
        else if(N<4){
            for(int j=0;j<M;++j)
                for(int k=0;k<(1<<N);++k)
                    F[j][k]=1e6;
            for(int k=0;k<(1<<N);++k){
                F[0][k]=0;
                for(int i=0;i<N;++i)
                    F[0][k]+=(A[getPos(i,0)]!=((k>>i)&1));
            }
            for(int j=1;j<M;++j)
                for(int k1=0;k1<(1<<N);++k1)
                    for(int k2=0;k2<(1<<N);++k2)
                        if(isRight(k1,k2,N)){
                            tmp=0;
                            for(int i=0;i<N;++i)
                                tmp+=(A[getPos(i,j)]!=((k2>>i)&1));
                            F[j][k2]=min(F[j][k2],F[j-1][k1]+tmp);
                        }
            for(int k=0;k<(1<<N);++k)
                ans=min(ans,F[M-1][k]);
            printf("%d\n",ans);
        }
        else if(M<4){
            for(int i=0;i<N;++i)
                for(int k=0;k<(1<<M);++k)
                    F[i][k]=1e6;
            for(int k=0;k<(1<<M);++k){
                F[0][k]=0;
                for(int j=0;j<M;++j)
                    F[0][k]+=(A[getPos(0,j)]!=((k>>j)&1));
            }
            for(int i=1;i<N;++i)
                for(int k1=0;k1<(1<<M);++k1)
                    for(int k2=0;k2<(1<<M);++k2)
                        if(isRight(k1,k2,M)){
                            tmp=0;
                            for(int j=0;j<M;++j)
                                tmp+=(A[getPos(i,j)]!=((k2>>j)&1));
                            F[i][k2]=min(F[i][k2],F[i-1][k1]+tmp);
                        }
            for(int k=0;k<(1<<M);++k)
                ans=min(ans,F[N-1][k]);
            printf("%d\n",ans);
        }
    }
    return 0;
}

总结

整体做的还不错。

Codeforces Round #663 (Div. 2)训练小结

标签:codeforce   names   步骤   排列   ret   long   using   div   base   

原文地址:https://www.cnblogs.com/dayu2001/p/13780739.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!