• 清北学堂2018年1月省选强化班模拟考试2


    期望得分:40+80+30=150

    实际得分:80+70+0=150

    T1

    LYK loves string(string)

    Time Limit:1000ms   Memory Limit:128MB

    题目描述

    LYK喜欢字符串,它认为一个长度为n的字符串一定会有n*(n+1)/2个子串,但是这些子串是不一定全部都不同的,也就是说,不相同的子串可能没有那么多个。LYK认为,两个字符串不同当且仅当它们的长度不同或者某一位上的字符不同。LYK想知道,在字符集大小为k的情况下,有多少种长度为n的字符串,且该字符串共有m个不相同的子串。

    由于答案可能很大,你只需输出答案对1e9+7取模后的结果即可。

    输入格式(string.in)

    一行3个数n,m,k。

    输出格式(string.out)

        一行,表示方案总数。

    输入样例

    2 3 3

    输出样例

    6

    样例解释

    共有6种可能,分别是ab,ac,ba,bc,ca,cb。

    数据范围

    对于20%的数据:1<=n,k<=5。

    对于40%的数据:1<=n<=5,1<=k<=1000000000。

    对于60%的数据:1<=n<=8,1<=k<=1000000000。

    对于100%的数据:1<=n<=10,1<=m<=100,1<=k<=1000000000。

    Hint

    本题非常easy。

    k再大也没有用,最多就用n种字符,最后乘个组合数即可

    搜索出用i(i<=n)种字符,有m种不同子串的字符串的个数 f[i]

    ans= Σ f[i]*C(k,i)

    搜索的时候每次只往后扩增一个新字母

    即 若当前字母为i,下一个字母的范围为[1,i+1]

    设字符集大小为S

    这样对于搜出的每种方案 * S的阶乘 即为 用 S 种 字符的答案

    判断一个字符串内有多少种不同的字串时,用哈希

    #include<cstdio>
    #include<algorithm>
    
    using namespace std;
    
    typedef long long LL;
    
    const int mod=1e9+7;
    
    int n,m;
    
    int a[11];
    LL has[11],b[11];
    
    int f[11]; 
    
    int inv[11];
    
    LL Pow(LL a,int b)
    {
        LL res=1;
        for(;b;a*=a,b>>=1)
            if(b&1) res*=a;
        return res;
    }
    
    void dfs(int now,int cnt,int lim)
    {
        if(cnt>lim || n-now+1<lim-cnt) return;
        if(now==n+1)
        {
            for(int i=1;i<=n;++i) has[i]=has[i-1]*10+a[i];
            int sum=0;
            for(int len=1;len<=n;++len) 
            {
                for(int i=1;i+len-1<=n;++i) b[i]=has[i+len-1]-has[i-1]*Pow(10,len); 
                sort(b+1,b+n+1-len+1);
                for(int i=1;i+len-1<=n;++i) if(b[i]!=b[i-1]) sum++;
            }
            if(sum==m) f[lim]++;
            return;
        }
        for(int i=1;i<=cnt;++i) a[now]=i,dfs(now+1,cnt,lim);
        a[now]=cnt+1; dfs(now+1,cnt+1,lim);
    }
    
    int getC(int x,int y)
    {
        int sum=1;
        for(int i=x-y+1;i<=x;++i) sum=1LL*sum*i%mod;
        for(int i=1;i<=y;++i) sum=1LL*sum*inv[i]%mod;
        return sum;
    }
    
    int pow(int a,int b)
    {
        int res=1;
        for(;b;a=1LL*a*a%mod,b>>=1)
            if(b&1) res=1LL*res*a%mod;
        return res;
    }
    
    int main()
    {
        freopen("string.in","r",stdin);
        freopen("string.out","w",stdout); 
        int k;
        scanf("%d%d%d",&n,&m,&k);
        int t=min(n,k);
        for(int i=1;i<=t;++i) dfs(1,0,i);
        LL bit=1;
        for(int i=1;i<=t;++i) 
        {
            inv[i]=pow(i,mod-2);
            bit*=i;
            f[i]=f[i]*bit%mod;
        }
        int ans=0;
        for(int i=1;i<=t;++i) ans=(ans+1LL*f[i]*getC(k,i)%mod)%mod;
        printf("%d",ans); 
    }
    View Code

    考场80分找规律代码

    #include<cstdio>
    #include<iostream>
    
    using namespace std;
    
    const int mod=1e9+7;
    
    typedef long long LL;
    
    int main()
    {
        freopen("string.in","r",stdin);
        freopen("string.out","w",stdout);
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        if(m<n || m>n*(n+1)/2)  cout<<0;
        else if(n==m) cout<<k; 
        else if(m==n*(n+1)/2) 
        {
            LL sum=k;
            for(int i=1;i<n;++i) sum=sum*(k-i)%mod;
            cout<<sum;
        }
        else if(n==2)  cout<<(LL)k*(k-1)/2%mod;
        else if(n==3)
        {
            if(m==4) cout<<'0';
            else if(m==5) cout<<(LL)k*(k-1)%mod*3%mod;
        }
        else if(n==4)
        {
            if(m==5 || m==6) cout<<0;
            else if(m==7) cout<<(LL)k*(k-1)%mod*3%mod;
            else if(m==8) cout<<(LL)k*(k-1)%mod*4%mod;
            else if(m==9) cout<<(LL)k*(k-1)%mod*(k-2)%mod*6%mod;
        }
        else if(n==5)
        {
            if(m<=8) cout<<0;
            else if(m==9) cout<<(LL)k*(k-1)%mod*3%mod;
            else if(m==10) cout<<0;
            else if(m==11) cout<<(LL)k*(k-1)%mod*10%mod;
            else if(m==12) cout<<(LL)k*(k-1)%mod*2%mod*((k-2)*3%mod+1)%mod;
            else if(m==13) cout<<(LL)k*(k-1)%mod*(k-2)%mod*19%mod;
            else if(m==14) cout<<(LL)k*(k-1)%mod*(k-2)%mod*(k-3)%mod*10%mod;
        }
        else if(n==6)
        {
            if(m<=10) cout<<0;
            else if(m==11) cout<<(LL)k*(k-1)%mod*3%mod;
            else if(m==12 || m==13) cout<<0;
            else if(m==14) cout<<(LL)k*(k-1)%mod*10%mod;
            else if(m==15) cout<<(LL)k*(k-1)%mod*3%mod*(2*k-1)%mod;
            else if(m==16) cout<<(LL)k*(k-1)%mod*9%mod;
            else if(m==17) cout<<(LL)k*(k-1)%mod*(k-2)%mod*45%mod;
            else if(m==18) cout<<(LL)k*(k-1)%mod*(k-2)%mod*((k-1)*10%mod+19)%mod;
            else if(m==19) cout<<(LL)k*(k-1)%mod*(k-2)%mod*(k-3)%mod*55%mod;
            else if(m==20) cout<<(LL)k*(k-1)%mod*(k-2)%mod*(k-3)%mod*(k-4)%mod*15%mod;
        }
        else if(n==7)
        {
            if(m!=27) cout<<0;
            else cout<<(LL)k*(k-1)%mod*(k-2)%mod*(k-3)%mod*(k-4)%mod*(k-5)%mod*21%mod;
        }
        else if(n==8)
        {
            if(m!=35) cout<<0;
            else cout<<(LL)k*(k-1)%mod*(k-2)%mod*(k-3)%mod*(k-4)%mod*(k-5)%mod*(k-6)%mod*28%mod;
        }
        else if(n==9)
        {
            if(m!=44) cout<<0;
            else cout<<(LL)k*(k-1)%mod*(k-2)%mod*(k-3)%mod*(k-4)%mod*(k-5)%mod*(k-6)%mod*(k-7)%mod*36%mod;
        }
        else if(n==10)
        {
            if(m!=54) cout<<0;
            else cout<<(LL)k*(k-1)%mod*(k-2)%mod*(k-3)%mod*(k-4)%mod*(k-5)%mod*(k-6)%mod*(k-7)%mod*(k-8)%mod*45%mod;
        }
    }
    View Code

    T2

    LYK loves graph(graph)

    Time Limit:2000ms   Memory Limit:128MB

    题目描述

    LYK喜欢花花绿绿的图片,有一天它得到了一张彩色图片,这张图片可以看做是一张n*m的网格图,每个格子都有一种颜色去染着,我们用-1至n*m-1来表示一个格子的颜色。特别地,-1代表这个颜色是黑色,LYK不喜欢黑色!

    LYK想将剪下这张图片中的一张子图片来(四联通块),使得这个子图片不存在黑色的格子,并且至少有k个不同的颜色。

    但是每个格子有自己的脾气,特别的,第i行第j列这个格子如果被LYK选中了,LYK需要花费相应的代价。LYK想花费尽可能少的代价来剪下一张满足自己要求的图片。

    输入格式(graph.in)

        第一行三个整数,n,m,k.

        接下来n行,每行m个数,表示图片中每个格子的颜色,每个数在-1到n*m-1之间。

      接下来n行,每行m个数,表示选择每个位置所需要的代价。

    输出格式(graph.out)

    一行,表示最小代价和。

    输入样例

    3 3 3

    0 0 1

    2 3 3

    -1 2 1

    3 1 5

    4 10 1

    9 3 4

    输出样例

    7

    数据范围

    对于20%的数据:1<=n,m,k<=4。

    对于另外30%的数据:不同的颜色数<=10(不包括-1)。

    对于再另外30%的数据:1<=n<=2,1<=m<=15。

    对于100%的数据:1<=n,m<=15,1<=k<=7,1<=ai,j<=100000。

    数据保证一定有解。

    听到标算的我一口老血喷了出来。。。

    首先这题肯定是斯坦纳树(除非你想写插头DP)

    但是颜色总数高达225种,没法状态压缩

    但是询问只要求有7种颜色,所以就可以大开脑洞:

    把225种颜色随机映射成7种颜色,然后做斯坦纳树!!!

    我们来分析分析它的正确率:

    首先可以肯定的是我们算出的答案只会大于等于最优解

    因为原本不同的颜色可能被随机映射为相同的颜色,原本相同的颜色随机映射后一定不同

    对于最优解中的7种颜色来说,

    每种颜色都有7种映射方案,所以一共有7^7种映射方案

    而只有这7种颜色映射玩之后还是7种颜色,才有可能算出最优解,这种情况一共有 7! 种

    所以随机映射做斯坦纳树一次 的 正确率 为 7!/  7^7  ≈ 0.006 = 0.6% 

    错误率=99.4%

    那么如果随机映射做斯坦纳树T次,错误率就是 99.6%  ^ T 

    如果T=400,错误率 ≈ 9%

    那么正确率  = 91%

    你还可以再多做几遍,正确率还是蛮高的。。。。。。

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream> 
    #include<algorithm>
    
    using namespace std;
    
    #define N 16 
    
    int n,m,k;
    int col[N][N],val[N][N];
    
    int a[N*N],mp[N*N];
    
    int ncol[N][N];
    
    int dp[N][N][1<<7];
    
    struct node
    {
        int x,y;
        node(int x=0,int y=0):x(x),y(y) {}
    };
    queue<node>q;
    
    bool vis[N][N];
    
    int dx[4]={-1,0,1,0};
    int dy[4]={0,1,0,-1};
    
    int ans=2e9;
    
    void read(int &x)
    {
        x=0; int f=1; char c=getchar();
        while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } 
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
        x*=f;
    }
    
    void spfa(int s)
    {
        node now;
        int sx,sy,nx,ny;
        while(!q.empty())
        {
            now=q.front();
            q.pop();
            sx=now.x; sy=now.y;
            vis[sx][sy]=false;
            for(int i=0;i<4;++i)
            {
                nx=sx+dx[i]; ny=sy+dy[i];
                if(nx<=0 || nx>n || ny<=0 || ny>m || ncol[nx][ny]==-1) continue;
                if(dp[nx][ny][s]>dp[sx][sy][s]+val[nx][ny]) 
                {
                    dp[nx][ny][s]=dp[sx][sy][s]+val[nx][ny];
                    if(!vis[nx][ny]) q.push(node(nx,ny)),vis[nx][ny]=true;
                }
            }
        }
    }
    
    void Steiner()
    {
        memset(dp,63,sizeof(dp));
        int oo=dp[0][0][0];
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j) 
                if(ncol[i][j]!=-1) dp[i][j][1<<ncol[i][j]]=val[i][j];
        int S=1<<k;
        for(int s=1;s<S;++s)
        { 
            for(int i=1;i<=n;++i)
                for(int j=1;j<=m;++j)
                {
                    for(int t=(s-1)&s;t;t=(t-1)&s)
                        dp[i][j][s]=min(dp[i][j][s],dp[i][j][t]+dp[i][j][s^t]-val[i][j]);
                    if(dp[i][j][s]<oo) q.push(node(i,j)),vis[i][j]=true;
                }
            spfa(s);
        }
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j) ans=min(ans,dp[i][j][S-1]); 
    }
    
    int main()
    {
        freopen("graph.in","r",stdin);
        freopen("graph.out","w",stdout);
        srand(1000); 
        int tot=0;
        read(n); read(m); read(k);
        for(int i=1;i<=n;++i) 
            for(int j=1;j<=m;++j)  read(col[i][j]),tot=max(tot,col[i][j]);
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j) read(val[i][j]);
        int T=300;
        tot++;
        for(int i=0;i<tot;++i) a[i]=i;
        while(T--)
        {
            random_shuffle(a,a+tot);
            for(int i=0;i<k;++i) mp[a[i]]=i;
            for(int i=k;i<tot;++i) mp[a[i]]=rand()%k;
            for(int i=1;i<=n;++i)
                for(int j=1;j<=m;++j)
                    if(col[i][j]==-1) ncol[i][j]=-1; else ncol[i][j]=mp[col[i][j]];
            Steiner();
        } 
        printf("%d",ans);
    }
    View Code

    期望80实际70暴力

    说好的不包括-1呢。。。

    不过没判-1拿了30里面的20,这数据准是随机的。。。

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define N 16
    
    int n,m,k;
    int col[16][16],val[16][16];
    
    bool tag;
    int num,first[N*N];
    
    int dx[4]={-1,0,1,0};
    int dy[4]={0,1,0,-1};
    
    void read(int &x)
    {
        x=0; int f=1; char c=getchar();
        while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); }
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
        x*=f;
    }
    
    void init()
    {
        read(n); read(m); read(k);
        memset(first,-1,sizeof(first));
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
            {
                read(col[i][j]);
                if(col[i][j]==-1) tag=true;
                else if(first[col[i][j]]==-1) first[col[i][j]]=num++;
            }
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                read(val[i][j]);
    }
    
    bool inmap(int x,int y)
    {
        if(!x || !y || x>n || y>m) return false;
        return true;
    }
    
    bool ok(int s)
    {
        int cnt=0;
        for(int i=1,bit=1;i<=30;++i,bit<<=1) cnt+=bool(s&bit);
        return cnt>=k;
    }
    
    namespace force1
    {
        bool use[5][5];
        bool vis[5][5];
        
        int sum,ans;
        
        bool use_col[N*N];
        
        void dfs2(int x,int y)
        {
            sum++;
            vis[x][y]=true;
            int nx,ny;
            for(int i=0;i<4;++i)
            {
                nx=x+dx[i]; ny=y+dy[i];
                if(inmap(nx,ny) && !vis[nx][ny] && use[nx][ny]) dfs2(nx,ny);
            }
        }
        
        bool connect()
        {
            int sx=0,sy=0,tot=0;
            for(int i=1;i<=n;++i)
                for(int j=1;j<=m;++j)
                    if(use[i][j])
                    {
                        tot++;
                        if(!sx) sx=i,sy=j;
                    }
            sum=0;
            memset(vis,false,sizeof(vis));
            dfs2(sx,sy);
            return sum==tot;
        }
        
        void judge()
        {
            if(!connect()) return;
            int cnt=0,ccnt=0;
            memset(use_col,0,sizeof(use_col));
            for(int i=1;i<=n;++i)
                for(int j=1;j<=m;++j)
                    if(use[i][j]) 
                    {
                        if(col[i][j]==-1) return;
                        cnt+=val[i][j];
                        if(!use_col[col[i][j]])
                        {
                            use_col[col[i][j]]=true;
                            ccnt++;
                        }
                    }
            if(ccnt<k) return;
            ans=min(ans,cnt);
        }
        
        void dfs(int x,int y)
        {
            if(y==m+1)
            {
                if(x==n) 
                {
                    judge();
                    return;
                }
                dfs(x+1,1);
                return;
            }
            dfs(x,y+1);
            use[x][y]=true;
            dfs(x,y+1);
            use[x][y]=false;
        }
        
        void work()
        {
            ans=2e9;
            dfs(1,1);
            cout<<ans;
        }
    }
    
    namespace force2
    {
        int ans;
        
        void dfs(int now,int endd,int type,int color,int cost)
        {
            if(now==endd+1)
            {
                 if(ok(color)) ans=min(ans,cost);
                return;
            }
            int ncolor,ncost;
            if(col[1][now]!=-1 && col[2][now]!=-1) 
            {
                ncolor=color|(1<<col[1][now])|(1<<col[2][now]);
                ncost=cost+val[1][now]+val[2][now];
                dfs(now+1,endd,0,ncolor,ncost);
            }
            if((!type || type==1) && col[1][now]!=-1)
            {
                ncolor=color|(1<<col[1][now]);
                ncost=cost+val[1][now];
                dfs(now+1,endd,1,ncolor,ncost);
            }
            if((!type || type==2) && col[2][now]!=-1)
            {
                ncolor=color|(1<<col[2][now]);
                ncost=cost+val[2][now];
                dfs(now+1,endd,2,ncolor,ncost);
            }
        }
        
        void work()
        {
            ans=2e9;
            for(int i=1;i<=m;++i)
                for(int j=i;j<=m;++j)
                    dfs(i,j,0,0,0);
            cout<<ans;
        }
    }
    
    namespace force3
    {
        int f[N][N][1024];
    
        struct node
        {
            int x,y;        
            node(int x_=0,int y_=0) : x(x_),y(y_) { }
        };
        
        queue<node>q;
        
        bool vis[N][N];
        
        void spfa(int s)
        {
            node now;
            int nx,ny;
            while(!q.empty())
            {
                now=q.front();
                q.pop();
                vis[now.x][now.y]=false;
                for(int i=0;i<4;++i)
                {
                    nx=now.x+dx[i];
                    ny=now.y+dy[i];
                    if(!inmap(nx,ny)) continue;
                    if(f[now.x][now.y][s]+val[nx][ny]<f[nx][ny][s])
                    {
                        f[nx][ny][s]=f[now.x][now.y][s]+val[nx][ny];
                        if(!vis[nx][ny]) q.push(node(nx,ny)),vis[nx][ny]=true;
                    }
                }
            }
        }
        
        void work()
        {
            for(int i=1;i<=n;++i)
                for(int j=1;j<=m;++j)
                    col[i][j]=first[col[i][j]];
            memset(f,63,sizeof(f));
            for(int i=1;i<=n;++i)
                for(int j=1;j<=m;++j)
                    f[i][j][1<<col[i][j]]=val[i][j];
            int S=1<<num; int oo=f[0][0][0];
            for(int s=1;s<S;++s)
            {
                for(int i=1;i<=n;++i)
                    for(int j=1;j<=m;++j)
                    {
                        for(int t=s-1;t;t=(t-1)&s)
                            f[i][j][s]=min(f[i][j][s],f[i][j][t]+f[i][j][s^t]-val[i][j]);
                        if(f[i][j][s]<oo) q.push(node(i,j)),vis[i][j]=true;
                    }
                spfa(s);
            }
            int ans=2e9;
            for(int s=1;s<S;++s)
                if(ok(s))
                {
                    for(int i=1;i<=n;++i)
                        for(int j=1;j<=m;++j)
                            ans=min(ans,f[i][j][s]);
                }
            cout<<ans;
        }
    }
    
    int main()
    {
        freopen("graph.in","r",stdin);
        freopen("graph.out","w",stdout);
        init();
        if(n<=4 && m<=4 && k<=4) force1::work();
        else if(n<=2 && m<=15) force2::work();
        else force3::work();
    }
    View Code

    T3

    LYK loves rabbits(rabbits)

    Time limit:1000ms     Memory limit:128MB

    题目描述

    LYK喜欢兔子,它在家中养了3只兔子。

    有一天,兔子不堪寂寞玩起了游戏,3只兔子排成一排,分别站在a,b,c这3个位置。

    游戏的规则是这样的,重复以下步骤k次:选择两个不同的兔子A和B,假如它们位于X与Y,A可以从X跳到Y+Y-X处,但是跳跃时是不允许一下子跳过两只兔子的,也就是说第三只兔子不在[min{X,Y+Y-X},max{X,Y+Y-X}]处。

    现在3只小兔子的位置分别到了x,y,z(3只兔子长得一样,即三只兔子跳完之后的顺序可以变化)处,但是它们忘记一开始是怎么跳的了,想让你帮它们还原跳法。但这个问题非常easy,于是LYK要求你输出方案总数。

    保证答案有解。

    由于答案巨大,你只需输出答案对1e9+7取模后的结果就可以了。

    输入格式(rabbits.in)

    第一行3个数a,b,c。

    第二行3个数x,y,z。

    第三行一个数k。

    数据保证3只兔子的起始位置a,b,c严格递增且3只兔子最终的位置x,y,z严格递增。

    输出格式(rabbits.out)

    一行表示方案总数。

    输入样例1

    0 2 5

    0 2 5

    2

    输出样例1

    3

    输入样例2

    0 2 4

    0 2 4

    2

    输出样例2

    2

    样例解释

    对于样例1:共有3种跳法,第一次跳完后的位置分别是{0,-2,5},{4,2,5},{0,8,5}。

    数据范围

    对于10%的数据k=1。J

    对于30%的数据k<=10。

    对于另外20%的数据a=x,b=y,c=z。

    对于再另外20%的数据a-b=b-c。

    对于再再另外20%的数据a,b,c与x,y,z之间不超过10步可达。

    对于100%的数据k<=100,|a|,|b|,|c||x|,|y|,|z|<=10^18。

    如果能由外往里跳,那么只能跳一个

    中间那个可以往外跳,有向左和向右两种方式

    所以跳的路径是一棵二叉树

    设起始位置在A号节点,终止位置在B号节点

    令f[i][j][k] 表示A 和 LCA的距离为i,B 和 LCA的距离为j,还剩下k步可以跳的方案数

    一、对于一般的一对A和B(不在根节点,且LCA不是A或B)来说,有两种决策:

    1、A向上跳,跳到 i-1 j  k-1

    2、A向下跳,A往左往右跳一个样,跳到 i+1 j k-1,方案数*2

    二、若A是LCA

    如果B也是LCA,即A和B在同一个位置,那可以

    1、A往上跳,跳到 i j+1 k-1

    2、A往下跳,跳到 i+1 j k-1 方案数*2

    如果B不是LCA,

    1、A往上跳,跳到 i j+1 k-1

    2、A往下跳,跳到非B所在的子树 i+1 j k-1;跳到B所在的子树 i j-1 k-1

    注意,A有可能是二叉树的根节点,这样A不能向上跳

    此时i=0,j>B的深度,特判这种情况

    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    typedef long long LL;
    
    const int mod=1e9+7;
    
    #define N 101
    
    LL a0[N],b0[N],c0[N];
    LL x0[N],y0[N],z0[N];
    
    int f[N][N][N];
    
    int k1,k2;
    
    int dfs(int i,int j,int k)
    {
        if(!i && !j && !k) return 1;
        if(i+j>k) return 0;
        if(!i && j>k2) return 0;
        if(f[i][j][k]!=-1) return f[i][j][k];
        if(!i) 
        {
            if(!j) f[i][j][k]=(dfs(0,1,k-1)+dfs(1,0,k-1)*2%mod)%mod;
            else f[i][j][k]=((dfs(0,j+1,k-1)+dfs(0,j-1,k-1))%mod+dfs(1,j,k-1))%mod;
        }
        else f[i][j][k]=(dfs(i-1,j,k-1)+dfs(i+1,j,k-1)*2%mod)%mod; 
        return f[i][j][k];
    }
    
    int main()
    {
        freopen("rabbits.in","r",stdin);
        freopen("rabbits.out","w",stdout);
        int k;
        scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&a0[0],&b0[0],&c0[0],&x0[0],&y0[0],&z0[0]);
        scanf("%d",&k);
        bool root=false;
        while(k1<k)
        {
            if(b0[k1]-a0[k1]==c0[k1]-b0[k1]) break;
            if(b0[k1]-a0[k1]<c0[k1]-b0[k1])
            {
                k1++; 
                a0[k1]=b0[k1-1];
                b0[k1]=2*b0[k1-1]-a0[k1-1];
                c0[k1]=c0[k1-1];
            }
            else
            {
                k1++;
                a0[k1]=a0[k1-1];
                b0[k1]=2*b0[k1-1]-c0[k1-1];
                c0[k1]=b0[k1-1];
            }
        }
        while(k2<k)
        {
            if(y0[k2]-x0[k2]==z0[k2]-y0[k2]) break;
            if(y0[k2]-x0[k2]<z0[k2]-y0[k2])
            {
                k2++; 
                x0[k2]=y0[k2-1];
                y0[k2]=2*y0[k2-1]-x0[k2-1];
                z0[k2]=z0[k2-1];
            }
            else
            {
                k2++;
                x0[k2]=x0[k2-1];
                y0[k2]=2*y0[k2-1]-z0[k2-1];
                z0[k2]=y0[k2-1];
            }
        }
        int l1,l2; bool tag=false;
        for(l1=0;l1<=k1 && !tag;++l1)
            for(l2=0;l2<=k2 && !tag;++l2)
                if(a0[l1]==x0[l2] && b0[l1]==y0[l2] && c0[l1]==z0[l2]) tag=true; 
        l1--; l2--;
        memset(f,-1,sizeof(f));
        printf("%d",dfs(l1,l2,k));
    }
    View Code

    考场爆零原因:用%d读long long

    Summary

    1、本场考试150分虽然是rank3,但150分的有8个,T3直接输出1拿到10分就可以脱颖而出

    2、考场上的一分钟都不能放弃,到了最后也要垂死挣扎,特判之类的东西全打上,多扑腾会儿

    3、T1正解是搜索,我在考场上是打表找规律,只找全了n<=6的,>6的只找到了m等于能取到的最大值和次大值的规律,期望是40分,结果后面60%的数据有40%的数据m是最/次大值,这就多得了40分,考场上还觉得没有什么用犹豫了好久才打上,所以如果写的是特判之类的,不要放过任何对的idea,说不定你就判到了数据呢。(对于这种搜索题数据为梯度内极端数据可能性比较大)

    4、T2暴力80分,因为实际数据与题面中的数据描述不符,拿了70分,那个正解随机性算法是当时的我无论如何也想不到的,在这种情况下,一定要拿满暴力分

    5、一定要特别注意long long的读入与输出,不仅仅是lld与I64d的问题,考场上用%d读long long,自己造的小数据没有问题,测试数据全>int。这种蠢到不能再蠢得问题不能出现第二次

    6、加强搜索,T1竟然没看出来是道搜索题

    7、谁说随机性的、正确率不是100%的算法就不可能成为正解了?在大量的操作下,错误率大大的降低。要注重一些非完美算法,也多思考一些非完美的解题思路(毕竟目前对我来说省选及以上难度比赛中想出正解的概率是很小的),不一定非要是有名字的算法呀!!

  • 相关阅读:
    麦茶商务的网站
    jQuery Ajax 实例 ($.ajax、$.post、$.get)
    关于meta知多少
    WebApp之Meta标签
    html5开发之viewport使用
    bootstrap
    8.8&8.9 dp训练小结
    2019.8.10小结
    2019.8.17 小结
    [NOI2001]炮兵阵地 题解
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8404293.html
Copyright © 2020-2023  润新知