【CF】Codeforces Round #533 (Div. 2)

说实话,感觉cf题目质量确实参差不齐,这套的质量真的比不上我之前做的几套。 虽然也做过几场,但能够感受到,一般div2和div1搭配的题目(div2后面的题作为div1前若干题)的时候质量要更高。这场主要是比手速? https://codeforces.com/contest/1105

A

水题模拟
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>

using namespace std;

int n;
int sm;
int a[1005];
int T,ans=0x3f3f3f3f;
int gsum(int t) {
    int om = 0;
    for(int i=1;i<=n;i++) {
        om += max(0,abs(a[i]-t)-1);
    }
    return om;
}
int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=100;i++) {
        int O = gsum(i);
        if(O<ans) {
            ans = O; T = i;
        }
    }
    printf("%d %d",T,ans);
}

B

水题模拟
#include<iostream>
#include<algorithm>
#include<cstdio>

using namespace std;
const int maxn = 2e5+5;
char ss[maxn];
int n,k,lx[maxn];
int MJ(char t) {
    int level = 0;
    for(int i=1;i<=n;i++) {
        if(ss[i]==t) {
            lx[i] = lx[i-1] + 1;
            if(lx[i]==k) lx[i] = 0 , ++ level;
        } else lx[i] = 0;
    }
    return level;
}
int ANS;
int main() {
    scanf("%d%d",&n,&k);
    scanf("%s",&ss[1]);
    for(char o='a';o<='z';o++) {
        ANS = max(ANS,MJ(o));
    }
    printf("%d",ANS);
}

C

水题dp
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>

using namespace std;
const int mod = 1e9+7;
int add(int x,int y) { x+=y; return x>=mod?x-mod:x; }
int sub(int x,int y) { x-=y; return x<0?x+mod:x; }
int mul(int x,int y) { return 1ll*x*y%mod; }
int n,l,r;
int NUM[3];
int f[200005][3];
int main() {
    scanf("%d%d%d",&n,&l,&r);
    NUM[0] = (r/3) - ((l-1)/3);
    NUM[1] = ( (r/3) + (r%3>=1) ) - ( ((l-1)/3) + ((l-1)%3>=1) );
    NUM[2] = ( (r/3) + (r%3>=2) ) - ( ((l-1)/3) + ((l-1)%3>=2) );
    f[0][0] = 1;
    for(int i=1;i<=n;i++) {
        f[i][0] = add( mul(f[i-1][1],NUM[2]) , add( mul(f[i-1][0],NUM[0]) , mul(f[i-1][2],NUM[1]) ) );
        f[i][1] = add( mul(f[i-1][1],NUM[0]) , add( mul(f[i-1][0],NUM[1]) , mul(f[i-1][2],NUM[2]) ) );
        f[i][2] = add( mul(f[i-1][1],NUM[1]) , add( mul(f[i-1][0],NUM[2]) , mul(f[i-1][2],NUM[0]) ) );
    }
    printf("%d",f[n][0]);
}

D

水题bfs
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;

int n,m,p;
int s[12];
char SY[1005][1005];
int TM[1005][1005];
int tim;
struct pr{
    int x,y,tm; 
};
queue<pr>q[10];
vector<pr>ve[12];
int dx[4] = {1,-1,0,0};
int dy[4] = {0,0,-1,1};
int ZY[12];
int ZL[1005][1005];
int main() {
    scanf("%d%d%d",&n,&m,&p);
    for(int i=1;i<=p;i++) {
        scanf("%d",&s[i]);
    }
    ++tim;
    for(int i=1;i<=n;i++) {
        scanf("%s",&SY[i][1]);
        for(int j=1;j<=m;j++) {
            if(SY[i][j]>='1'&&SY[i][j]<='9')  q[SY[i][j]-'0'].push((pr){i,j,s[SY[i][j]-'0']-1} ),SY[i][j]='.';
        }
    }
    for(int tt=0;tt<=n*m;tt++) {
        for(int i=1;i<=p;i++) {
            auto &Q = q[i];
            for(;Q.size();Q.pop()) {
                int x = Q.front().x; int y = Q.front().y; int t = Q.front().tm;
                if(SY[x][y]!='.') continue;
                if(ZL[x][y]) continue;
                if(t/s[i]!=tt) break;
                ZL[x][y] = i;
                ZY[i]++;
                for(int j=0;j<4;j++) {
                    int nx = x+dx[j]; int ny = y+dy[j];
                    Q.push((pr){nx,ny,t+1});
                }
            }
        }
    }
    for(int i=1;i<=p;i++) printf("%d ",ZY[i]);
}

E

很容易转化为图论的一般图最大独立集模型,对于拥有相同换名字时间的人连边,那么互相不能选。 对于图论的一般图最大独立集有个结论就是其补图的最大团(就是在无向图找到一个最大的完全图) 方法1:考虑爆搜会有很多重的状态,时间复杂度2^40炸了,加上记忆化就好了(虽然算不来时间复杂度orz)
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<vector>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef vector<int> ve;
map<string,int>dy;
ve ans,now;
int n,m;
bool ma[45][45];
set<int>se;
map<ll,int>dp;
int f(ll mk) {
    if(dp.count(mk)) return dp[mk];
    int x ;
    for(int i=0;i<n;i++) if(!((mk>>i)&1) ) { x=i; break;}
    ll nmk = mk;
    for(int i=1;i<=n;i++) 
        if( (!ma[i][x+1]) && (!(mk&(1LL<<(i-1) ))) )
            nmk ^= (1LL<<(i-1) );
    return dp[mk] = max(f(mk^(1LL<<x)),f(nmk)+1);
}
int main() {
    cin>>m>>n;
    int cc = 0;
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) ma[i][j] = 1;
    int op;
    for(int i=1;i<=m;i++) {
        cin>>op;
        if(op==1) {
            for(auto x:se) {
                for(auto y:se) {
                    ma[x][y] = 0;
                }
            }
            se.clear();
        } else {
            string ss; cin>>ss;
            if(!dy.count(ss)) dy[ss] = ++cc;
            se.insert(dy[ss]);
        }
    }
    for(auto x:se) {
        for(auto y:se) {
            ma[x][y] = 0;
        }
    }
    dp[(1LL<<n)-1] = 0;
    printf("%d",f(0));
}
方法2:random_shuflle多次,贪婪的选点。O(n*次数)
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
map<string,int>dy;
string tt;
int n,m,cc,id[45],ans;
long long f[45],now;
int main() {
    cin>>m>>n;
    for(int i=1;i<=m;i++) {
        int op; cin>>op;
        if(op==1) {
            for(int j=0;j<n;j++) {
                if( (now>>j)&1) f[j]|=now;
            }
            now = 0;
        } else {
            cin>>tt; 
            if(!dy.count(tt) ) dy[tt] = cc++;
            now|=(1LL<<dy[tt]);
        }
    }
    for(int j=0;j<n;j++) {
        if( (now>>j)&1) f[j]|=now;
    }
    now = 0;
    for(int i=0;i<n;i++) id[i] = i;
    for(int j=0;j<1e6;j++) {
        random_shuffle(id,id+n);
        now = cc = 0;
        for(int i=0;i<n&&now!=(1LL<<n)-1;i++) {
            if(! ((now>>id[i])&1) ) now|=f[id[i]],++cc;
        }
        ans = max(ans,cc);
    }
    printf("%d",ans);
}
posted @ 2019-01-23 21:03  Newuser233  阅读(6)  评论(0编辑  收藏  举报