zoukankan      html  css  js  c++  java
  • 牛客网Wannafly模拟赛

    A矩阵
    时间限制:1秒 空间限制:131072K

    题目描述

    给出一个n * m的矩阵。让你从中发现一个最大的正方形。使得这样子的正方形在矩阵中出现了至少两次。输出最大正方形的边长。

    输入描述:

    第一行两个整数n, m代表矩阵的长和宽;
    接下来n行,每行m个字符(小写字母),表示矩阵;

    输出描述:

    输出一个整数表示满足条件的最大正方形的边长。
    示例1

    输入

    5 10
    ljkfghdfas
    isdfjksiye
    pgljkijlgp
    eyisdafdsi
    lnpglkfkjl

    输出

    3

    备注:

    对于30%的数据,n,m≤100;
    对于100%的数据,n,m≤500;

    hash好题,推荐去卿学姐讲堂学hash

    每一个字符串都hash一下和长度有关的哈希值

    #include<cstdio>
    #include<algorithm>
    #define N 510
    typedef unsigned long long LL;
    const LL D1=101,D2=193;
    int n,m,i,j,l,r,mid,ans,t;
    char a[N][N];
    LL pow1[N],pow2[N],h[N][N],tmp,tmp2,has[N*N];
    bool check(int x)
    {
        for(i=1; i<=n; i++)
        {
            for(tmp=0,j=1; j<x; j++)
                tmp=tmp*D1+a[i][j],h[i][j]=0;
            for(j=x; j<=m; j++)
            {
    
                h[i][j]=tmp=tmp*D1-pow1[x]*a[i][j-x]+a[i][j];
            }
        }
        for(t=0,i=x; i<=m; i++)
        {
            for(tmp=0,j=1; j<x; j++)
                tmp=tmp*D2+h[j][i];
            for(j=x; j<=n; j++)
            {
    
                has[t++]=tmp=tmp*D2-pow2[x]*h[j-x][i]+h[j][i];
            }
        }
        std::sort(has,has+t);
        for(i=1; i<t; i++)
            if(has[i-1]==has[i])
                return 1;
        return 0;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(i=1; i<=n; i++)
        {
            scanf("%s",a[i]+1);
            for(j=1; j<=m; j++)
                a[i][j]-='a'-1;
        }
        l=1,r=n<m?n:m;
        for(pow1[0]=pow2[0]=i=1; i<=r; i++)
            pow1[i]=pow1[i-1]*D1,
                    pow2[i]=pow2[i-1]*D2;
        while(l<=r)
            if(check(mid=(l+r)>>1))
                l=(ans=mid)+1;
            else r=mid-1;
        return printf("%d",ans),0;
    }
    B树
    时间限制:1秒 空间限制:131072K

    题目描述

    shy有一颗树,树有n个结点。有k种不同颜色的染料给树染色。一个染色方案是合法的,当且仅当对于所有相同颜色的点对(x,y),x到y的路径上的所有点的颜色都要与x和y相同。请统计方案数。

    输入描述:

    第一行两个整数n,k代表点数和颜色数;
    接下来n-1行,每行两个整数x,y表示x与y之间存在一条边;

    输出描述:

    输出一个整数表示方案数(mod 1e9+7)。
    示例1

    输入

    4 3
    1 2
    2 3
    2 4

    输出

    39

    备注:

    对于30%的数据,n≤10, k≤3;
    对于100%的数据,n,k≤300。

    B这个是个假树啊,只要找到组合数的贡献是k*(k-1)*……*(k-i)就好的

    #include <stdio.h>
    const int MD=1e9+7;
    int dp[301][301];
    int main()
    {
        int n,k;
        scanf("%d%d",&n,&k);
        dp[0][0]=1;
        for(int i=1; i<n; i++)
        {
            dp[i][0]=1;
            for(int j=1; j<=i; j++)
                dp[i][j]=(dp[i-1][j-1]+dp[i-1][j])%MD;
        }
        int kk=k,ans=0;
        for(int i=0;i<=k&&i<=n;i++)
        {
            ans=(ans+dp[n-1][i]*1LL*kk%MD)%MD;
            kk=1LL*kk*(k-i-1)%MD;
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    WebGL——osg框架学习一
    webgl绘制粗线段
    ThreeJS实现波纹粒子效果
    WebGL——水波纹特效
    WebGL之shaderToy初使用
    有效提升职场竞争力
    Windows结构化异常处理浅析
    一起学习Boost标准库--Boost.StringAlgorithms库
    科学计算工具-Numpy初探
    进程动态拦截注入API HOOK
  • 原文地址:https://www.cnblogs.com/BobHuang/p/7443575.html
Copyright © 2011-2022 走看看