zoukankan      html  css  js  c++  java
  • THUPC2021题解

    持续更新中……

    从哪里跌倒,从哪里爬起!

    B

    建立主席树,对每次询问算出答案,然后二分位置判断

    代码:略

    F

    裸DP是O(n^3p^2),用bitset优化是O(n^3p^2/w),然后考虑随机游走问题,在二维平面每次随机向一个方向游走,距离不超过√n级别,而本题也是从6种方案中随机选择1种,于是便可以将游走范围缩小到√n,复杂度降为O(n^2p^2/w)

    代码:知道思路就很容易,懒写了

    G

    裸的背包,只是需要优化。k%s==0的部分每次都要做,可以直接预处理,然后每次DP时就无须访问了,卡卡常数就过了

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2021,mod=1e9+7;
    int n,m,k,ans,f[12][N],g[12][N];
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        g[0][0]=1;
        for(int s=1;s<=m;++s)
        if(k%s==0)for(int i=1;i<=n;++i)for(int j=m;j>=s;--j)
        g[i][j]=(g[i][j]+g[i-1][j-s])%mod;
        for(int i=1;i<=m;++i)
        {
            memcpy(f,g,sizeof f);
            for(int s=1;s<=i;++s)
            if(1ll*i*k%s==0&&k%s!=0)
            for(int j=1;j<=n;++j)for(int p=i;p>=s;--p)f[j][p]=(f[j][p]+f[j-1][p-s])%mod;
            ans=(ans+f[n][i])%mod;
        }
        printf("%d",ans);
    }

    H

    容易发现答案大时一定是k+1或者k+2,n若被k+1整除,则答案是k+1,反之是k+2

    其次发现答案至少是k+1,然后可以将剩余的分配,然后每次往每一堆里塞一个就行,设n=a(k+1)+b,答案是k+1+[b/a]

    但要注意的是如果n小于k+1则每个颜色不同,要特判一下

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+7;
    int n,k,x;
    char nn[N],xx[N];
    void check(int a,int b)
    {
        if(a==b)puts("Correct, but it doesn't necessarily mean that you can win the Turing Award.");
        if(a<b)puts("Wrong, don't cheat me, you are too far away from the Turing Award.
    1");
        if(a>b)puts("Wrong, don't cheat me, you are too far away from the Turing Award.
    0");
    }
    int main()
    {
        scanf("%s%d%s",nn+1,&k,xx+1);
        if(strlen(xx+1)>=4)
        {puts("Wrong, don't cheat me, you are too far away from the Turing Award.
    1");return 0;}
        for(int i=1;i<=strlen(xx+1);++i)x=x*10+xx[i]-'0';
        if(strlen(nn+1)>5)
        {
            for(int i=1;i<=strlen(nn+1);++i)n=(n*10+nn[i]-'0')%(k+1);
            if(!n)check(k+1,x);else check(k+2,x);
        }
        else{
            for(int i=1;i<=strlen(nn+1);++i)n=n*10+nn[i]-'0';
            if(n<k+1)check(n,x);
            else if(n%(k+1)==0)check(k+1,x);
            else check(k+2+(n%(k+1)-1)/(n/(k+1)),x);
        }
    }

    I

    数位DP,注意Nim获胜条件,2^m枚举子集,f[i][S][j]表示从高到低dp到第i位,目前被卡上限的集合是S,低位向这位进j次,注意j的范围是[0,m-1]

    代码:略

    K

    等我学了python程设再来写这题

  • 相关阅读:
    【原】使用Spring自带的JdbcTemplate。
    【原】MyBatis执行DDL:create table,drop table等等
    【转】java获取当前路径的几种方法
    【原】Java程序调用远程Shell脚本
    [转载] 使用Kettle进行数据迁移(ETL)
    appium原理
    python之global关键字的用法
    python之selenium定位(xpath)
    android 稳定性monkey测试
    python之selenium随记(几种等待的用法)
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/14915554.html
Copyright © 2011-2022 走看看