zoukankan      html  css  js  c++  java
  • Codeforces Round #177 (Div. 1) 题解【ABCD】

    Codeforces Round #177 (Div. 1)

    A. Polo the Penguin and Strings

    题意

    让你构造一个长度为n的串,且里面恰好包含k个不同字符,让你构造的字符串字典序最小。

    题解

    先abababab,然后再把k个不同字符输出,那么这样就是最少

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    string s;
    int main()
    {
        int n,k;
        scanf("%d%d",&n,&k);
        if(n>1&&k==1){
            cout<<"-1"<<endl;
            return 0;
        }
        if(k>n){
            cout<<"-1"<<endl;
            return 0;
        }
        if(k==1){
            for(int i=1;i<=n;i++)
                printf("a");
        }else{
            for(int i=0;i<n-k+2;i++){
                if(i%2==0)printf("a");
                else printf("b");
            }
            for(int i=2;i<k;i++)
                printf("%c",'a'+i);
    
        }
        printf("
    ");
    }
    

    B. Polo the Penguin and Houses

    题意

    给你n个城市,你在x城市,那么下一步会走到a[x]城市。

    现在你从前k个城市出发,最终都会走到1号点,从后面n-k个城市出发,不会走到1节点,问你一共有多少种方案。

    题解

    k很小,所以直接dfs就好了,可以先预处理一下一些没必要dfs的部分。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int mod = 1e9+7;
    int n,k,cnt=0;
    int a[10],flag,vis[10];
    long long ans = 0;
    int dfs2(int x){
        if(x==1)return 1;
        if(vis[x])return 0;
        vis[x]=1;
        dfs2(a[x]);
    }
    void check()
    {
        flag=1;
        for(int i=2;i<=k&&flag;i++){
            memset(vis,0,sizeof(vis));
            flag&=dfs2(i);
        }
        if(flag)cnt++;
    }
    void dfs(int x){
        if(x==k+1){
            check();
            return;
        }
        for(int i=1;i<=k;i++)
            a[x]=i,dfs(x+1);
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        ans=k;
        for(int i=0;i<n-k;i++)
            ans=(ans*(n-k))%mod;
        dfs(2);
        cout<<(ans*1ll*cnt)%mod<<endl;
    }
    

    C - Polo the Penguin and XOR operation

    题意

    让你构造一个排列,使得sigma(i^a[i])最大

    题解

    手动玩一玩可以发现,实际上是可以异或互补的,所以我们把那些互补的都给补上,答案就是最大的。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6+7;
    int vis[maxn],n,a[maxn],ans[maxn];
    
    int main(){
        scanf("%d",&n);
        for(int i=n;i>=0;i--){
            if(vis[i])continue;
            int tmp=i,len=0;
            while(tmp){
                tmp/=2;
                len++;
            }
            int Up=(1<<len)-1;
            int x2=Up^i;
            ans[i]=x2;
            ans[x2]=i;
            vis[i]=vis[x2]=1;
        }
        long long Ans = 0;
        for(int i=0;i<=n;i++)
            Ans+=i^ans[i];
        cout<<Ans<<endl;
        for(int i=0;i<=n;i++)
            cout<<ans[i]<<" ";
        cout<<endl;
    }
    

    288D - Polo the Penguin and Trees

    题意

    给你一棵树,问你有多少对不相交路径

    题解

    反过来做,然后容斥搞一搞,减去相交的对数。

    分为子树外和子树内,都扣一扣就好了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 8e4+6;
    int n;
    long long s[maxn];
    long long ans = 0;
    vector<int> E[maxn];
    void dfs(int x,int f){
        s[x]=1;
        long long tmp = 0;
        for(int i=0;i<E[x].size();i++){
            int v=E[x][i];
            if(v==f)continue;
            dfs(v,x);
            tmp+=1ll*s[x]*s[v];
            s[x]+=s[v];
        }
        ans-=1ll*tmp*(tmp+2LL*s[x]*(n-s[x]));
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<n;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            E[a].push_back(b);
            E[b].push_back(a);
        }
        ans=1ll*n*(n-1LL)/2LL*(n*(n-1LL)/2LL);
        dfs(1,0);
        cout<<ans<<endl;
    }
  • 相关阅读:
    NYOJ 625 笨蛋的难题(二)
    NYOJ 102 次方求模
    ZJU Least Common Multiple
    ZJUOJ 1073 Round and Round We Go
    NYOJ 709 异形卵
    HDU 1279 验证角谷猜想
    BNUOJ 1015 信息战(一)——加密程序
    HDU 1202 The calculation of GPA
    "蓝桥杯“基础练习:字母图形
    "蓝桥杯“基础练习:数列特征
  • 原文地址:https://www.cnblogs.com/qscqesze/p/6133280.html
Copyright © 2011-2022 走看看