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

    题目描述

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

    输入描述:

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

    输出描述:

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

    输入

    5 10
    ljkfghdfas
    isdfjksiye
    pgljkijlgp
    eyisdafdsi
    lnpglkfkjl

    输出

    3

    备注:

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



    数据还是挺好的,不二分超时,用set超内存。得必须自己写字符串二维hash;

    此题是原题,URAL

    分析:他一定是满足二分性质的~~~

    二维字符串hash,没听说过,其实和子矩阵和类似,就是用了一种数学方法,可以通过相加减得到一个子矩阵的hash值。

    先一行一行hash,然后是列,组合起来。

    逻辑还是很好写的,可以当做一个小板子。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef unsigned long long ull;
    const int N = 500 + 10,INF = 0x3f3f3f3f;
    const int seed = 131,Seed = 1789;
    
    char ori[N][N];
    ull hash1[N][N],seed_pow[N];    ///row
    ull hash2[N][N],Seed_pow[N];    ///col
    ull a[N*N];
    int n,m;
    
    
    bool check(int k) {
        int tot = 0;
    
        for(int i = k; i <= n; i++)
        {
            for(int j = k ; j <= m; j++)
            {
                ull tmp = hash2[i][j] - hash2[i-k][j]*Seed_pow[k] - hash2[i][j-k]*seed_pow[k] + hash2[i-k][j-k]*Seed_pow[k]*seed_pow[k];
                a[++tot] = tmp;
            }
        }
    
        sort(a+1,a+1+tot);
        for(int i = 1; i <= tot - 1; i++)
            if(a[i]==a[i+1]) return true;
        return false;
    
    }
    
    int main()
    {
        freopen("in.txt","r",stdin);
        seed_pow[0] = Seed_pow[0] = 1;
        for(int i = 1; i < N; i++)
        {
            seed_pow[i] = seed_pow[i-1]*seed;
            Seed_pow[i] = Seed_pow[i-1]*Seed;
        }
    
        scanf("%d%d",&n,&m);
    
        for(int i = 1; i <= n; i++) scanf("%s",ori[i]+1);
    
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
                hash1[i][j] = hash1[i][j-1]*seed + ori[i][j];
    
        for(int i = 1; i <= m; i++)
            for(int j = 1; j <= n; j++)
                hash2[j][i] = hash2[j-1][i]*Seed + hash1[j][i];
    
        int ans = 0;
        int l = 0,r = min(n,m);
    
        while(l<=r) {
            int mid = (l + r) >> 1;
            if(check(mid)) ans = mid,l = mid + 1;
            else r = mid - 1;
        }
        printf("%d
    ",ans);
    
    
        return 0;
    }
    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 131072K,其他语言262144K
    64bit IO Format: %lld

    题目描述

    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。

     顿时对牛客上的题目好感+1。

    此题看上去是一个染色,其实任意两个相同颜色的点对,之间都的一个颜色,那就是一个联通分量全是一个颜色。

    树,就可以看做是一个点集合,挑哪些点染同一种颜色。显然是DP做法。

    d[i][j] :前 i 个点,染 j 种颜色的方案数。

    d[i][j] = d[i-1][j] + d[i-1][j-1]*(k+1-j);

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int mod = 1e9+7;
    
    long long d[305][305];
    
    int main()
    {
        int n,k;
        scanf("%d%d",&n,&k);
    
        for(int i = 0; i < n-1; i++) {
            int x,y;
            scanf("%d%d",&x,&y);
        }
    
        memset(d,0,sizeof(d));
        d[0][0] = 1;
    
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= k; j++) {
                d[i][j] = (d[i-1][j] + d[i-1][j-1]*(k+1-j))%mod;
            }
        }
    
        long long ans = 0;
        for(int j = 1; j <= k; j++)
            ans = (ans + d[n][j])%mod;
        cout<<ans<<endl;
    
    
        return 0;
    }
  • 相关阅读:
    局部变量和全局变量
    Javascript高级编程学习笔记(26)—— 函数表达式(4)私有变量
    Javascript高级编程学习笔记(25)—— 函数表达式(3)模仿块级作用域
    Javascript高级编程学习笔记(24)—— 函数表达式(2)闭包
    Javascript高级编程学习笔记(23)—— 函数表达式(1)递归
    Javascript高级编程学习笔记(22)—— 对象继承
    Javascript高级编程学习笔记(21)—— 对象原型
    Javascript高级编程学习笔记(20)—— 创建对象
    Javascript高级编程学习笔记(19)—— 对象属性
    Javascript高级编程学习笔记(18)—— 引用类型(7)单体内置对象
  • 原文地址:https://www.cnblogs.com/TreeDream/p/7846372.html
Copyright © 2011-2022 走看看