zoukankan      html  css  js  c++  java
  • 湖南雅礼培训 1.1

    练习赛

    一、题目概览

    中文题目名称

    红与蓝

    猜数列

    英文题目名称

    tree

    rab

    hidden

    可执行文件名

    tree

    rab

    hidden

    输入文件名

    tree.in

    rab.in

    hidden.in

    输出文件名

    tree.out

    rab.out

    hidden.out

    时间限制

    1s

    1s

    1s

    空间限制

    256MB

    256MB

    256MB

    测试点数目

    10

    10

    25

    测试点分值

    10

    10

    4

    题目类型

    传统

    传统

    传统

    比较方式

    全文比较

    spj

    全文比较

    是否有部分分

    二、注意事项:

    1.文件名(程序名和输入输出文件名)必须使用小写。

    2.C/C++中函数main()的返回值类型必须是int,程序正常结束时的返回值必须是0。

    3.开启O2优化,栈空间开大至256M。

    树(tree)

    【题目描述】

        有n个点,第i个点的限制为度数不能超过ai。

        现在对于每一个s(1<=s<=n),问从这n个点中选出s个点组成有标号无根树的方案数。

    【输入数据】

           第一行一个整数表示n。

           第二行n个整数a1~an。

    【输出数据】

    一个n个整数,第i个整数表示s=i时的答案。

    答案模1004535809

    【样例输入】

    3

    2 2 1

    【样例输出】

           3 3 2

    【数据范围】

           对于20%的数据,n≤6。

    对于60%的数据,n≤50。

    对于100%的数据,n≤100。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define maxn 101
    #define mod 1004535809
    using namespace std;
    int n,a[maxn],ans[maxn],t[maxn],num,b[maxn];
    bool vis[maxn];
    void dfs2(int pos){
        if(pos==num-1){
            ans[num]++;
            if(ans[num]>=mod)ans[num]-=mod;
            return;
        }
        for(int i=1;i<=num;i++){
            int ii=b[i];
            if(t[ii]!=a[ii]-1){
                t[ii]++;
                dfs2(pos+1);
                t[ii]--;
            }
        }
    }
    void dfs1(int pos,int id){
        if(pos==n+1){
            return;
        }
        for(int i=id;i<=n;i++){
            if(!vis[i]){
                b[pos]=i;
                vis[i]=1;
                if(pos>=3)num=pos,dfs2(1);
                dfs1(pos+1,i+1);
                vis[i]=0;
            }
        }
    }
    int main(){
    //    freopen("Cola.txt","r",stdin);
        freopen("tree.in","r",stdin);freopen("tree.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        for(int i=n;i>=1;i--){
            if(a[i]>n-1)a[i]=n-1;
            else break;
        }
        ans[1]=n;ans[2]=(n-1)*n/2;
        dfs1(1,1);
        for(int i=1;i<=n;i++)printf("%d ",ans[i]);
        return 0;
    }
    暴力
    #include<iostream>
    #include<cstdio>
    #define maxn 101
    #define mod 1004535809
    int n,m,ans,f[maxn][maxn][maxn*2],a[maxn],c[maxn*2][maxn];
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            a[i]=min(a[i],n);a[i]--;
        }
        c[0][0]=1;
        for(int i=1;i<=n;i++){
            c[i][0]=1;
            for(int j=1;j<=i;j++)c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
        }
        f[0][0][0]=1;//到第i个点,选了j个点,purfer数列中有k个点的方案数 
        for(int i=0;i<n;i++)
            for(int k=0;k<n;k++)
                for(int j=0;j<=n;j++)
                    if(f[i][k][j]){
                        f[i+1][k][j]=(f[i+1][k][j]+f[i][k][j])%mod;
                        for(int t=0;t<=a[i+1];t++)(f[i+1][k+1][j+t]+=1LL*f[i][k][j]*c[j+t][t]%mod)%=mod;
                    }
        for(int k=1;k<=n;j++){
            if(k==1)ans=n;
            else ans=f[n][k][k-2];
            ans=(ans+mod)%mod;
            printf("%d ",ans);
        }
        return 0;
    }
    100分 purfer数列dp

    红与蓝(rab)

    【题目描述】

        给定一棵树,初始时非叶节点均为无色,叶节点会是红色、蓝色或无色。

           小红和小蓝轮流给无色叶子染色(小红染红色,小蓝染蓝色,小红先染)。所有叶子染完后,非叶节点的颜色将被逐一确定:一个非叶节点的颜色是它所有儿子的颜色中出现较多的那个(保证有奇数个儿子)。最后,根是谁的颜色谁就获胜。

           求小红是否能赢,若能赢,求出第一步选择哪些叶子能赢。

    【输入数据】

           第一行一个整数t表示数据组数。

           每组数据第一行一个整数n表示节点数。

    第二行n个整数,第i个整数fi表示i的父亲,保证f1=0。

    第三行n个整数,第i个整数gi表示i的初始颜色(0表示红色,1表示蓝色,-1表示无色)。

    【输出数据】

    每组数据输出一行。

    若小红能赢,先输出一个整数m表示第一步可以选的叶子数,接下来m个整数表示那些叶子的编号,从小到大输出。若你只知道小红能赢,你可以只输出一行一个整数0。

    否则输出一个整数-1。

    【样例输入】

    2

    2

    0 1

    -1 -1

    2

    0 1

    -1 1

    【样例输出】

           1 2

           -1

    【数据范围】

           对于20%的数据,t=1,n≤20。

    对于60%的数据,n≤2000。

    对于100%的数据,t<=10,n≤100000。

    若你只判断对了胜负,可以获得该测试点一半的分数。

    猜数列(hidden)

    【题目描述】

    有一个长度为m的,由1到9之间的数构成的未知数列a。

    你现在有n个线索,每个线索都是用如下方式生成的:

    (1)选择序列a的某一个位置p作为开始;

    (2)选择某个方向(向左或向右);

    (3)从p出发往你选择的方向走,每遇到一个之前未出现的数就将它加到线索中。

    现在你需要求出满足所有线索的长度最小的序列的长度。

    【输入数据】

    输入文件的第一行为一个整数n,表示线索的数量。

    接下来n行,每行有若干个以0结尾的整数,表示一条线索。保证一条线索中的数在[1,9]中且不会出现相同的数。

    【输出数据】

    如果无解请输出-1,否则输出可能的最小长度。

    【样例输入1

           5

    1 2 0

    3 4 0

    1 4 3 0

    3 1 4 2 0

    1 2 4 3 0

    【样例输出1

           7

    【样例输入2

    3
    1 2 0
    2 3 0
    3 4 0

    【样例输出2

           -1

    【数据范围】

    对于20%的数据,答案不超过10。

    对于另外40%的数据,保证存在一个最优解,使得所有线索都可以通过向右遍历得到。

    对于100%的数据,1≤n≤10。

  • 相关阅读:
    spring----RESTful API
    spring----模块之间的通讯问题
    PHP错误与异常处理
    微信支付:curl出错,错误码:60
    jquery判断checkbox是否选中
    微信网页授权的问题
    TP5更新数据成功,但判断结果不符
    190719有个织梦专题标题长度限制问题
    判断手机浏览器还是微信浏览器(PHP)
    TP5关联模型出现疑问,待解决
  • 原文地址:https://www.cnblogs.com/thmyl/p/8167958.html
Copyright © 2011-2022 走看看