zoukankan      html  css  js  c++  java
  • Codeforces Round #599 (Div. 2)

    A. Maximum Square

    直接O(kn^2)枚举最大边长

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int k,n,a[1005];
    int main(){
        cin>>k;
        while(k--){
            cin>>n;
            for(int i=1;i<=n;++i) cin>>a[i];
            for(int i=n;i>=1;--i){
                int sum=0;
                for(int j=1;j<=n;++j)
                    if(a[j]>=i) ++sum;
                if(sum>=i){printf("%d
    ",i);break;}
            }
        }return 0;
    }
    View Code

    B1. Character Swap (Easy Version)

    合法当且仅当两串恰有2对相同的不同字符

    (即$a[i]==a[j],b[i]==b[j],a[i]!=b[i]$)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int T,n,p[256][256];
    char a[10005],b[10005];
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            scanf("%s",a+1);
            scanf("%s",b+1);
            memset(p,0,sizeof(p));
            for(int i=1;i<=n;++i)
                if(a[i]!=b[i])
                    ++p[a[i]][b[i]];
            int sum=0;
            for(int i='a';i<='z';++i)
                for(int j='a';j<='z';++j){
                    if(p[i][j]==2) ++sum;
                    if(p[i][j]==1||p[i][j]>2) sum=5;
                }
            puts(sum<=1?"Yes":"No");
        }return 0;
    }
    View Code

    B2. Character Swap (Hard Version)

    $<=2n$次交换意味着可以直接模拟

    不合法的情况当且仅当有字符在两串中出现次数为奇数

    设当前到第$i$位,$a[i]!=b[i]$

    直接枚举找与$a[i]$相同的字符$a[k]$或$b[k]$

    如果为$a[k]$,$swap(b[i],a[k])$

    如果为$b[k]$,选择任意一个下标$j$,$swap(a[j],b[k]),swap(a[j],b[i])$

    这样每位最多交换2次

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int T,n,m,p1[256],r1[200],r2[200];
    char a[53],b[53];
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            scanf("%s",a+1);
            scanf("%s",b+1);
            memset(p1,0,sizeof(p1));
            for(int i=1;i<=n;++i)
                ++p1[a[i]],++p1[b[i]];
            bool ok=1;
            for(int i='a';i<='z'&&ok;++i)
                if(p1[i]&1) ok=0;
            if(!ok){puts("No"); continue;}
            puts("Yes"); m=0;
            for(int i=1;i<=n;++i) if(a[i]!=b[i]){
                for(int j=i+1;j<=n;++j){
                    if(a[j]==a[i]){
                        r1[++m]=j;
                        r2[m]=i;
                        swap(a[j],b[i]);
                        break;
                    }
                    if(b[j]==a[i]){
                        r1[++m]=i+1;
                        r2[m]=j;
                        swap(a[i+1],b[j]);
                        r1[++m]=i+1;
                        r2[m]=i;
                        swap(a[i+1],b[i]);
                        break;
                    }
                }
            }
            printf("%d
    ",m);
            for(int i=1;i<=m;++i) printf("%d %d
    ",r1[i],r2[i]);
        }return 0;
    }
    View Code

    C. Tile Painting

    将$n$个点每隔$p-1(p>1,p|n)$个连边,求连通块个数

    可以发现存在$p_1,p_2$时,连通块个数=$gcd(p_1,p_2)$

    于是$O(sqrt n)$枚举$n$的约数判断一下就好了

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    ll n,m,p[300],tt,len;
    int main(){
        cin>>n; m=len=n;
        for(ll i=2,t=sqrt(n);i<=t;++i){
            if(m<i) break;
            if(m%i==0) p[++tt]=i;
            while(m%i==0) m/=i;
        }
        if(m>1) p[++tt]=m;
        for(int i=tt;i>=1;--i){
            if(len%p[i]){len=1; break;}
            len=p[i];
        }cout<<len;
        return 0;
    }
    View Code

    D. 0-1 MST

    可以把0边用并查集维护,最后求连通块个数

    但是$0$边过多

    于是大力套个线段树优化建图就完事了

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    #define N 100005
    int n,m,fa[N*5],id[N]; bool vis[N*5],ve[N*5];
    int rt,u,s[N*5],lc[N*5],rc[N*5];
    vector <int> g[N];
    
    int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    void uni(int x,int y){
        int r1=find(x),r2=find(y);
        if(r1!=r2) fa[r1]=r2;
    }
    #define mid (l+r)/2
    int build(int l,int r){
        int nw=++u;
        fa[nw]=nw;
        if(l==r){id[l]=nw; return nw;}
        lc[nw]=build(l,mid);
        rc[nw]=build(mid+1,r);
        return nw;
    }
    void link(int o,int l,int r,int x1,int x2,int k){
        if(x1<=l&&r<=x2){vis[o]=1; uni(o,k); return ;}
        if(x1<=mid) link(lc[o],l,mid,x1,x2,k);
        if(x2>mid) link(rc[o],mid+1,r,x1,x2,k);
    }
    void tree_uni(int o,int l,int r){
        if(vis[o]) for(int i=l;i<=r;++i) uni(o,id[i]);
        if(l==r) return ;
        tree_uni(lc[o],l,mid); tree_uni(rc[o],mid+1,r);
    }
    void Link(int I,int l,int r){
        link(rt,1,n,l,r,id[I]);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1,U,V;i<=m;++i){
            scanf("%d%d",&U,&V);
            g[U].push_back(V);
            g[V].push_back(U);
        }
        rt=build(1,n);
        for(int i=1;i<=n;++i){
            g[i].push_back(i);
            sort(g[i].begin(),g[i].end());
            int len=g[i].size();
            for(int j=0;j<len-1;++j){
                int l=g[i][j],r=g[i][j+1];
                if(l+1<r) Link(i,l+1,r-1);
            }
            if(1<g[i][0]) Link(i,1,g[i][0]-1);
            if(g[i][len-1]<n) Link(i,g[i][len-1]+1,n);
        }
        tree_uni(rt,1,n);
        int tot=0;
        for(int i=1;i<=n;++i){
            int Fa=find(id[i]);
            if(!ve[Fa]) ve[Fa]=1,++tot;
        }
        printf("%d",tot-1);
        return 0;
    }
    View Code

    E. Sum Balance

    WA#9......不管了先睡了(错乱)

  • 相关阅读:
    php学习笔记之一维数组
    MVC开发人员必备的五大工具
    ASP.NET MVC 3和Razor中的@helper
    Oracle表空间不足ORA-01654
    oracle创建计划任务
    淘宝下单高并发解决方案
    网站集成QQ登录功能
    jquery的一个模板引擎-zt
    Asp.net gzip压缩的启用
    Windows7下面手把手教你安装Django
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/11809752.html
Copyright © 2011-2022 走看看