• D5上


    好慌啊 0分??

    T1

    感觉是组合数,不知道对不对。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<ctime>
    using namespace std;
    const int P=1e9+7;
    long long  n,k,ans=1;
    int main()
    {
        freopen("cube.in","r",stdin);
        freopen("cube.out","w",stdout);
        scanf("%lld%lld",&n,&k);
        int x;
        for(int i=1;i<=n;i++)    scanf("%d",&x);
        for(int i=k+1;i<=n;i++)
        ans=(ans*i)%P;
        for(int i=2;i<=(n-k);i++)
        ans=(ans*i)%P;
        cout<<ans<<'
    ';
        return 0;
    }
    first

     完了组合数用错了,应该用逆元的。

    思路:
      其实就是说,在n个位置中,找出K个与原来不同的(1或0两种)。

      组合数公式n! / k!(n-k)!  因为数比较大,如果先取模再除 是不对的。

      用乘法逆元,/x %p等价于 *x^P-2 .

      也可以分解质因数,不知道哪根筋抽了,这都没想到。 

    T2 

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    using namespace std;
    const int N=1e5+100;
    int n,m,q;
    struct node{
        int x,y;
        int z;
    }a[N],ask[N];
    int f[N],tot;
    int find(int x)
    {
        while(x!=f[x])
            x=f[x]=f[f[x]];
        return x;
    }
    bool cmp(node u,node v)
    {    return u.z>v.z;}
    bool fan(node u,node v)
    {    return u.y<v.y;}
    int main()
    {
        freopen("warehouse.in","r",stdin);
        freopen("warehouse.out","w",stdout);
        scanf("%d%d%d",&n,&m,&q);
        for(int i=1;i<=m;i++)    
            scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
        for(int i=1;i<=q;i++)
        scanf("%d",&ask[i].z),ask[i].y=i;
        sort(a+1,a+1+n,cmp);sort(ask+1,ask+1+q,cmp);
        for(int i=1;i<=n;i++)    f[i]=i;
        
        tot=n;int ed=0,i=1,f1,f2;
        for(i=1;i<=q;i++)
        {
            while(a[ed+1].z>=ask[i].z)
            {
                ed++;
                f1=find(a[ed].x);f2=find(a[ed].y);
                if(f1!=f2)
                {
                    f[f1]=f2;tot--;
                }
            }
            ask[i].x=tot;
        }
        sort(ask+1,ask+q+1,fan);
        for(int i=1;i<=q;i++)
        printf("%d
    ",ask[i].x);
        return 0;
    }
    first

     应该写对了啊,0分。。。

    和昨天的题差不多,建一个最大生成树,在合并的过程中更新答案。 

    T3

    不会去重,甚至计数都不会。

    这道题的确不简单,因为一个字符串可能会得到多次,

    那我们就就想办法让这个字符串只得到一次,怎么操作那?

    维护两个数组a[i][j](表示长度为i的前缀,后面再加j字符就会重复的字符串数量)

          c[i][j](表示以j为开头,长度为i的字符串数量)

        (因为我们只需要考虑,字符串长度,和是否重复)

    最后把长度和为L的前缀和后缀字符根据乘法原理组合起来就是答案了。

    但是!这样做有漏洞!!

    原因是对于本来就是一个单词一部分的字符如coo,它能由co  前缀和 o后缀 组成,但我们却没有判定出co这个前缀。

     a c拼起来的基础是那个合法串从一个位置 开始 前缀变成不合法的了
    但是coo这个串,整个串都是合法的
  • 相关阅读:
    python3.5+flask+mysql
    Python魔法师
    Redis
    Socket
    Python线程
    Python全栈之路--Django ORM详解
    基本算法
    Python_Select解析
    如何做好一名DBA【转】
    解决MySQL忘记root密码
  • 原文地址:https://www.cnblogs.com/CLGYPYJ/p/7764944.html
Copyright © 2020-2023  润新知