• Codeforces Round #566 (Div. 2)


    AB

    签到(A过水已隐藏)

    #include<bits/stdc++.h>
    using namespace std;
    const int N=505;
    int n,m,vis[N][N];
    char mp[N][N];
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%s",mp[i]+1);
        if(n<=2||m<=2){puts("NO");return 0;}
        for(int i=2;i<n;i++)
        for(int j=2;j<m;j++)
        if(mp[i][j]=='*'&&mp[i-1][j]=='*'&&mp[i+1][j]=='*'&&mp[i][j-1]=='*'&&mp[i][j+1]=='*')
        {
            vis[i][j]=1;
            int k=i;
            while(k>1&&mp[k-1][j]=='*')vis[--k][j]=1;
            k=i;
            while(k<n&&mp[k+1][j]=='*')vis[++k][j]=1;
            k=j;
            while(k>1&&mp[i][k-1]=='*')vis[i][--k]=1;
            k=j;
            while(k<m&&mp[i][k+1]=='*')vis[i][++k]=1;
            for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            if(!vis[i][j]&&mp[i][j]=='*'){puts("NO");return 0;}
            puts("YES");
            return 0;
        }
        puts("NO");
    }
    View Code

    C

    首先要学会用vector<char>,然后每个串记录元音出现次数和最后的元音是什么,统计二者都相同的对数和只有一个相同的对数,直接贪心取。

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int>pii;
    const int N=1e5+7;
    int n,id[200];
    vector<char>a[N];
    vector<int>G[N*10][5];
    vector<pii>v1,v2;
    char str[N*10];
    void print(int x){for(int i=0;i<a[x].size();i++)printf("%c",a[x][i]);}
    int main()
    {
        scanf("%d",&n);
        memset(id,-1,sizeof id);
        id['a']=0,id['e']=1,id['o']=2,id['i']=3,id['u']=4;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",str+1);
            int len=strlen(str+1),num=0,yid=0;
            for(int j=1;j<=len;j++)
            {
                a[i].push_back(str[j]);
                if(id[str[j]]!=-1)num++,yid=id[str[j]];
            }
            G[num][yid].push_back(i);
        }
        for(int i=1;i<=1e6;i++)
        for(int j=0;j<5;j++)
        if(G[i][j].size()&&G[i][j].size()%2==0)
        {
            for(int k=0;k<G[i][j].size();k+=2)v1.push_back(pii(G[i][j][k],G[i][j][k+1]));
            G[i][j].clear();
        }
        else if(G[i][j].size())
        {
            int p=G[i][j][0];
            for(int k=1;k<G[i][j].size();k+=2)v1.push_back(pii(G[i][j][k],G[i][j][k+1]));
            G[i][j].clear();
            G[i][j].push_back(p);
        }
        for(int i=1;i<=1e6;i++)
        {
            int pre=-1;
            for(int j=0;j<5;j++)
            if(G[i][j].size())
            {
                if(pre==-1)pre=j;
                else v2.push_back(pii(G[i][pre][0],G[i][j][0])),pre=-1;
            }
        }
        if(v1.size()<=v2.size())
        {
            printf("%d
    ",v1.size());
            for(int i=0;i<v1.size();i++)
            {
                print(v2[i].first),printf(" "),print(v1[i].first),puts("");
                print(v2[i].second),printf(" "),print(v1[i].second),puts("");
            }
        }
        else{
            printf("%d
    ",v2.size()+(v1.size()-v2.size())/2);
            for(int i=0;i<v2.size();i++)
            {
                print(v2[i].first),printf(" "),print(v1[i].first),puts("");
                print(v2[i].second),printf(" "),print(v1[i].second),puts("");
            }
            for(int i=v2.size()+1;i<v1.size();i+=2)
            {
                print(v1[i-1].first),printf(" "),print(v1[i].first),puts("");
                print(v1[i-1].second),printf(" "),print(v1[i].second),puts("");
            }
        }
    }
    View Code

    D

    这题太难了吧,调不出来早知道去hack B了……细节贼多……首先发现选取的位置不是在重心就是叶子节点,然后显然先判断重心是否可行,判断方法大家应该都会。然后发现每种深度的叶子只要判断一个节点即可,发现种类数多时在深度小的时候就会被判掉,于是写过了。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+7;
    int n,siz,rt,flag,sz[N],mp[N],a[N];
    vector<int>G[N],vec[2];
    void dfs(int u,int fa)
    {
        sz[u]=1;
        int mx=0;
        for(int i=0;i<G[u].size();i++)if(G[u][i]!=fa)
        dfs(G[u][i],u),sz[u]+=sz[G[u][i]],mx=max(mx,sz[G[u][i]]);
        mx=max(mx,n-sz[u]);
        if(mx<siz)siz=mx,rt=u;
    }
    void dfs1(int u,int fa,int dep)
    {
        if(!a[dep])a[dep]=G[u].size();
        else if(a[dep]!=G[u].size())flag=1;
        sz[u]=1;
        for(int i=0;i<G[u].size();i++)
        if(G[u][i]!=fa)dfs1(G[u][i],u,dep+1),sz[u]+=sz[G[u][i]];
        if(G[u].size()==1)mp[dep]=u;
    }
    bool solve()
    {
        flag=0;
        memset(a,0,sizeof a);
        for(int i=0;i<G[rt].size();i++)dfs1(G[rt][i],rt,1);
        if(flag)return 0;
        for(int i=1;i<G[rt].size();i++)if(sz[G[rt][i]]!=sz[G[rt][0]])return 0;
        return 1;
    }
    int main()
    {
        scanf("%d",&n);
        if(n<=3){puts("1");return 0;}
        siz=n;
        for(int i=1,x,y;i<n;i++)scanf("%d%d",&x,&y),G[x].push_back(y),G[y].push_back(x);
        dfs(1,0);
        if(solve()){printf("%d",rt);return 0;}
        for(int i=0;i<n;i++)if(mp[i])
        {
            rt=mp[i];
            if(solve()){printf("%d",rt);return 0;}
        }
        puts("-1");
    }
    View Code

    E

    显然考虑f1、f2、f3和c出现的幂次数,然后构造3个3*3的矩阵和1个5*5的矩阵,直接转移即可。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod=1e9+7,gloid=1e9+6;
    int ans,f1,f2,f3,c;
    struct mat{
        int a[5][5];
        void clear(){memset(a,0,sizeof a);}
        void init()
        {
            memset(a,0,sizeof a);
            for(int i=0;i<5;i++)a[i][i]=1;
        }
        void prepare()
        {
            memset(a,0,sizeof a);
            a[0][0]=a[0][1]=a[1][0]=a[1][2]=a[2][0]=1;
        }
    }A;
    int qpow(int a,int b)
    {
        int ret=1;
        while(b)
        {
            if(b&1)ret=1ll*ret*a%mod;
            a=1ll*a*a%mod,b>>=1;
        }
        return ret;
    }
    mat operator*(mat a,mat b)
    {
        mat c;c.clear();
        for(int i=0;i<5;i++)
        for(int j=0;j<5;j++)
        for(int k=0;k<5;k++)
        c.a[i][j]=(c.a[i][j]+1ll*a.a[i][k]*b.a[k][j])%gloid;
        return c;
    }
    mat qpow(mat a,ll b)
    {
        mat ret;ret.init();
        while(b)
        {
            if(b&1)ret=ret*a;
            a=a*a,b>>=1;
        }
        return ret;
    }
    int main()
    {
        ll n;
        cin>>n>>f1>>f2>>f3>>c;
        A.prepare();
        A=qpow(A,n-3);
        ans=1ll*qpow(f1,A.a[2][0])*qpow(f2,A.a[1][0])%mod*qpow(f3,A.a[0][0])%mod;
        A.clear();
        for(int i=0;i<4;i++)A.a[i][0]=1;
        A.a[0][1]=A.a[1][2]=A.a[3][3]=A.a[4][3]=A.a[4][4]=1;
        A=qpow(A,n-3);
        ans=1ll*ans*qpow(c,2ll*(A.a[3][0]+A.a[4][0])%gloid)%mod;
        cout<<ans;
    }
    View Code

    F

    其实上就是要让值距离π/2更近,然后分成小于π/2的和大于π/2两类,对于每一类二分一下,找到最近的答案,然后用exgcd找到最小的位置即可。细节有点多很难讲的详细,具体见code吧。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll>pii;
    ll a,b,p,q;
    ll calc(ll a,ll b,ll c,ll n)
    {
        if(!n)return 0;
        ll ret=a/c*n*(n-1)/2+b/c*n;
        a%=c,b%=c;
        return ret+calc(c,(a*n+b)%c,a,(a*n+b)/c);
    }
    bool check1(ll mid)
    {return calc(2*p,3*q,2*q,b+1)-calc(2*p,3*q,2*q,a)>calc(2*p,3*q-mid-1,2*q,b+1)-calc(2*p,3*q-mid-1,2*q,a);}
    bool check2(ll mid)
    {return calc(2*p,3*q,2*q,b+1)-calc(2*p,3*q,2*q,a)-calc(2*p,3*q-mid,2*q,b+1)+calc(2*p,3*q-mid,2*q,a)<b-a+1;}
    void exgcd(ll a,ll b,ll&x,ll&y)
    {
        if(!b){x=1,y=0;return;}
        exgcd(b,a%b,y,x),y-=a/b*x;
    }
    ll find(ll t,ll mn)
    {
        t=t+q>>1;
        ll x,y,d;exgcd(p,q,x,y);
        x=(x%q+q)%q*t%q;
        if(x>=mn)return x;
        d=(mn-x-1)/q+1;
        return x+q*d;
    }
    int main()
    {
        int T;cin>>T;
        while(T--)
        {
            cin>>a>>b>>p>>q;
            ll d=__gcd(p,q),l,r,mid;
            p/=d,q/=d,l=0,r=2*q-1;
            while(l<r)
            {
                ll mid=l+r>>1;
                if(check1(mid))r=mid;else l=mid+1;
            }
            pii ans=pii(l,find(l,a));
            l=0,r=2*q-1;
            while(l<r)
            {
                mid=l+r+1>>1;
                if(check2(mid))l=mid;else r=mid-1;
            }
            ans=min(ans,pii(2*q-l,find(l,a)));
            cout<<ans.second<<endl;
        }
    }
    View Code

    result:rank12 rating=1838(用新号打的)

  • 相关阅读:
    线程间协作的两种方式:wait、notify、notifyAll和Condition
    Lock
    线程池ExecutorService的使用
    使用volatile的条件
    解决共享资源竞争
    并发时捕获异常
    Executor执行器
    BufferedReader 和BufferedWriter
    彻底理解Java的Future模式
    贝叶斯网络简介--翻译版
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/11007767.html
Copyright © 2020-2023  润新知