zoukankan      html  css  js  c++  java
  • 清北刷题班day3 morning

    P99
    zhx
    : 竞赛时间:???? 年?? 月?? 日??:??-??:??
    题目名称 a b c
    名称 a b c
    输入 a.in b.in c.in
    输出 a.out b.out c.out
    每个测试点时限 1s 1s 1s
    内存限制 256MB 256MB 256MB
    测试点数目 10 10 10
    每个测试点分值 10 10 10
    是否有部分分 无 无 无
    题目类型 传统 传统 传统
    注意 事项) (请务必仔细阅读) :
    P99 zhxa


    a
    【问题描述】
    你是能看到第一题的 friends 呢。
    ——hja
    怎么快速记单词呢?也许把单词分类再记单词是个不错的选择。何大爷给
    出了一种分单词的方法,何大爷认为两个单词是同一类的当这两个单词的各个
    字母的个数是一样的,如 dog 和 god。现在何大爷给了你?个单词,问这里总共
    有多少类单词。
    【输入格式】
    第一行一个整数?代表单词的个数。
    接下来?行每行一个单词。
    【输出格式】
    一行一个整数代表答案。
    【样例输入】
    3
    AABAC
    CBAAA
    AAABB
    【样例输出】
    2
    【数据范围与规定】
    70%的数据,1 ≤ ? ≤ 100。
    对于100%的数据,1 ≤ ? ≤ 10000,所有单词由大写字母组成。
    P99 zhxb

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<set>
    #include<cstdlib>
    #include<algorithm>
    
    #define N 10007
    
    using namespace std;
    int len,n;
    string ch;
    set<string>s;
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        cin>>n;
        for(int k=1;k<=n;k++)
        {
            cin>>ch;len=ch.length();
            sort(ch.begin(),ch.end());
            s.insert(ch);
        }
        printf("%d
    ",s.size());
        fclose(stdin);fclose(stdout);
        return 0;
    }


    b
    【问题描述】
    你是能看到第二题的 friends 呢。
    ——laekov
    长度为?的铁丝,你可以将其分成若干段,并把每段都折成一个三角形。你
    还需要保证三角形的边长都是正整数并且三角形两两相似,问有多少种不同的
    分法。
    【输入格式】
    一行一个整数?。
    【输出格式】
    一行一个整数代表答案对10 9 + 7取模之后的值。
    【样例输入 1
    6
    【样例输出 1】
    2
    【样例输入 2】
    9
    【样例输出 2】
    6
    【样例解释 2】
    (1,1,1),(2,2,2);(2,2,2),(1,1,1)算两种方案。
    【数据范围与规定】
    3。
    60%的数据,1 ≤ ? ≤ 1000。
    对于100%的数据,1 ≤ ? ≤ 10 6 。
    P99 zhxc

    /*
    首先计算周长为M的三角形有多少个,设为f[M]。设三角形的三边a,b,c满足a<=b<=c,那么分两种情况:
    (1)b=c,此时c的上限为(M-1)/2,下限为ceil(M/3)=(M+2)/3,所以此时的三角形个数为(M-1)/2-(M+2)/3+1;
    (2)b!=c,那么b<=c-1,因为a+b>c>c-1,因此一般来说有多少个三角形(a,b,c-1)就有多少个三角形(a,b,c),但是此时要减去a+b=c的情况。三角形(a,b,c-1)的个数就是f[M-1]。此时若a+b=c,即M-1=a+b+c-1=c+c-1,即M=2c,因此M必须为偶数。a+b=c=M/2,使得a+b=M/2的有序(a<=b)二元组有M/2/2。
    根据这两个可以得到计算f的递推关系。下面我们看怎么得到周长为M且三边满足Gcd(a,b,c)=1的三角形个数?这个可用于筛素数类似的方法得到。那么对于n,将其分成若干份,每份相等,那么不同的分法就是隔板法。
    ①相似三角形一定可以找到最小的那个,称为这类相似三角形的基。
    ②剩下就是一包夹杂容斥的递推:
    ③设w[i]为长度为i的铁丝的分法,一种分法的所有三角形边长除以gcd(a,b,c)得到的三角形都一样,且三边互质,设边长为a',b',c'。?
    ④若M=a+b+c,M'=a'+b'+c',设k=M/M',那么以a',b',c'为三边的三角形为基,用长度为M的铁丝能做出的方案数为2^(k-1) (杨辉三角第k层数字和公式)。?
    ⑤设g[i]为长度为i的铁丝分成边长为a,b,c(a<=b<=c)且gcd(a,b,c)=1的三角形的方案数。那么
      w[i]=g[p1]*2^(i/p1-1)+g[p2]*2^(i/p2-1)+…+g[pk]*2^(i/pk-1)(p为i的因数)。?
    ⑥设f[i]为长度为i的铁丝分成边长为a,b,c(a<=b<=c)的三角形的方案数。那么
      g[i]=f[i]-f[p1]-f[p2]-…-f[pk](p为i的因数)。(注意此处的f相当于g了,因为是f在刷新自己,因此不会出现因倍数而导致重复情况)
    ⑦接下来处理三角形三边合法(即f的递推):
      1.b==c,c最小为ceil(i/3),最大为floor((i-1)/2) 。?
      2.b<=b<=c-1的方案数,为f[i-1]。?
      第二种情况还要除去a+b=c的方案数。?
      若a+b=c,那么i=a+b+c=2*(a+b),a+b=i/2,
      这样的(a,b)有i/2/2对,此时i一定为偶数,所以i为偶数时要考虑这种情况
    */
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    const int N=5000005,mod=1000000007;
    int n,ans,cnt;
    int f[N],p[N];
    int main()
    {
        p[1]=1;
        for(int i=2; i<=N; i++)p[i]=(p[i-1]*2)%mod;
        f[3]=1;
        for(int i=4; i<=N; i++)
        {
            f[i]=f[i-1]+(i-1)/2-i/3+(i%3?0:1);
            if(i%2==0)f[i]-=i/4;
            f[i]%=mod;
            if(f[i]<0)f[i]+=mod;
        }
        for(int i=2; i<=N; i++)
            for(int j=2; i*j<=N; j++)
            {
                f[i*j]-=f[i];
                if(f[i*j]<0)f[i*j]+=mod;
            }
        while(~scanf("%d",&n))
        {
            ans=0;
            for(int i=1; i*i<=n; i++)
            {
                if(n%i!=0)continue;
                ans=(ans+1ll*f[i]*p[n/i])%mod;
                if(i*i!=n)ans=(ans+1ll*f[n/i]*p[i])%mod;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }


    c
    【问题描述】
    你是能看到第三题的 friends 呢。
    ——aoao
    在小学的时候,我们都学过正视图和左视图。现在何大爷用一些小方块摆了
    一个图形,并给出了你这个图形的左视图和正视图。现在何大爷希望知道,在给
    定正视图和左视图的情况下,原来的立体图形有多少种可能的情况?
    【输入格式】
    第一行两个整数?,?,代表在左视图和正视图中分别有多少列。
    第二?个整数,代表在左视图中从左至右每一列的高度。
    第三行?个整数,代表在正视图中从左至有每一列的高度。
    【输出格式】
    一行一个整数代表答案对10 9 + 9取模之后的值。
    【样例输入 1】
    2 2
    1 1
    1 1
    【样例输出 1】
    7
    【样例输入 2】
    4 5
    5 2 4 1
    5 2 4 0 1
    【样例输出 2】
    429287
    【数据规模与约定】
    21 ≤ ?,? ≤ 5,每列的最大高度不超过5。
    40%的数据,? + ? ≤ 18。
    对于100%的数据,1 ≤ ?,? ≤ 50,每列最

    /*
    排序
    容斥原理 
    emmmmm
    大概就是这么牛逼
    大佬的世界
    我们不懂
    不懂
    不懂
    就是不懂
    嘿嘿嘿
    不懂
    绝望
    就是不懂
    很绝望
    看不懂
    emmmm 
    */
    #include<cstdio>
    #include<algorithm>
    
    using namespace std;
    
    typedef long long LL;
    
    #define N 51
    #define H 10001
    const int mod=1e9+9;
    
    int a[H],b[H];
    int n,m;
    int C[N][N];
    
    void pre(int k)
    {
        for(int i=0; i<=k; i++) C[i][0]=1;
        for(int i=1; i<=k; i++)
            for(int j=1; j<=i; j++)
                C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
    }
    
    int pow(int a,int b)
    {
        int res=1;
        for(; b; b>>=1,a=1ll*a*a%mod)
            if(b&1) res=1ll*res*a%mod;
        return res;
    }
    
    int cal(int n,int m,int nn,int mm,int h)
    {
        int res=0,tmp;
        for(int i=0; i<=nn; ++i)
            for(int j=0; j<=mm; ++j)
            {
                tmp=1ll*pow(h,n*m-(n-i)*(m-j))*pow(h+1,(n-i)*(m-j)-(n-nn)*(m-mm))%mod*C[nn][i]%mod*C[mm][j]%mod;
                if((i+j)&1) res=((res-tmp)%mod+mod)%mod;
                else res+=tmp,res%=mod;
            }
        return res;
    }
    
    int main()
    {
        freopen("c.in","r",stdin);
        freopen("c.out","w",stdout);
        int x;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; ++i) scanf("%d",&x),a[x]++;
        for(int i=1; i<=m; ++i) scanf("%d",&x),b[x]++;
        pre(max(n,m));
        LL res=1;
        int nown=0,nowm=0;
        for(int i=10000; i>=0; i--)
            if(a[i] || b[i])
            {
                nown+=a[i];
                nowm+=b[i];
                res=1ll*res*cal(nown,nowm,a[i],b[i],i)%mod;
            }
        printf("%I64d",res);
    }
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    CSV文件读取类
    一个参数处理类
    记一个mysql的问题
    php问题小记
    wsl开nginx和php-fpm遇到的几个小问题
    debian apache2.4 virtual host 使用
    debian 安装 apache2和php7
    杂记整理三:php、thinkphp和sql
    杂记整理二:linux与程序安装
    杂记整理一:javascript, jQuery 以及 ECMAscript
  • 原文地址:https://www.cnblogs.com/L-Memory/p/7661451.html
Copyright © 2011-2022 走看看