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;
    }
  • 相关阅读:
    获取CheckBoxList当前选择项索引
    IE游览器与CMYK模式的JPEG格式图片不兼容
    jquery listbox左右移动 并且取值
    JS保留2位小数
    list.Contain 与 list.FindIndex()用法记录
    CSS 手型显示样式
    分页存储过程
    C#将datatable生成easyui的绑定tree 的json数据格式
    URL编码方法的比较
    UNIX I/O with TCP/IP
  • 原文地址:https://www.cnblogs.com/qscqesze/p/6133280.html
Copyright © 2011-2022 走看看