zoukankan      html  css  js  c++  java
  • 牛客练习赛1 A

    链接:https://www.nowcoder.com/acm/contest/2/A
    来源:牛客网

    题目描述

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

    输入描述:

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

    输出描述:

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

    输入

    5 10
    ljkfghdfas
    isdfjksiye
    pgljkijlgp
    eyisdafdsi
    lnpglkfkjl

    输出

    3

    备注:

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

    题解

    二分,字符串$hash$。

    可以二分答案,然后验证,验证的时候$O(n^2)$效率可以得到每一个正方形的$hash$值,判断一下即可,注意$hash$冲突,用了两次$hash$才过。

    #include<bits/stdc++.h>
    using namespace std;
    
    long long base[2];
    long long mod[2];
    const int maxn = 500 + 10;
    int n, m;
    char s[maxn][maxn];
    long long b[2][maxn * maxn];
    long long sum[2][maxn][maxn];
    long long h[2][maxn][maxn];
    pair<long long, long long> pi[maxn * maxn];
    
    void init() {
      base[0] = 131LL;
      base[1] = 313LL;
      mod[0] = 1e9 + 7;
      mod[1] = 1e9 + 7;
    }
    
    int check(int x) {
      for(int t = 0; t < 2; t ++) {
        for(int i = 0; i < n; i ++) {
          long long C = 0;
          for(int j = 0; j < x; j ++) {
            C = C * base[t] % mod[t];
            C = (C + s[i][j]) % mod[t];
          }
          sum[t][i][0] = C;
          for(int j = 1; j + x - 1 < m; j ++) {
            long long A = sum[t][i][j - 1];
            long long B = s[i][j - 1] * b[t][x - 1] % mod[t];
            A = (A - B + mod[t]) % mod[t];
            A = A * base[t] % mod[t];
            A = (A + s[i][j + x - 1]) % mod[t];
            sum[t][i][j] = A;
          }
        }
        for(int j = 0; j < m; j ++) {
          long long C = 0;
          for(int i = 0; i < x; i ++) {
            C = C * b[t][x] % mod[t];
            C = (C + sum[t][i][j]) % mod[t];
          }
          h[t][0][j] = C;
        }
        for(int i = 1; i + x - 1 < n; i ++) {
          for(int j = 0; j + x - 1 < m; j ++) {
            long long A = h[t][i - 1][j];
            long long B = sum[t][i - 1][j] * b[t][x * (x - 1)] % mod[t];
            A = (A - B + mod[t]) % mod[t];
            A = A * b[t][x] % mod[t];
            A = (A + sum[t][i + x - 1][j]) % mod[t];
            h[t][i][j] = A;
          }
        }
      }
      
      int sz = 0;
      for(int i = 0; i + x - 1 < n; i ++) {
        for(int j = 0; j + x - 1 < m; j ++) {
          pi[sz].first = h[0][i][j];
          pi[sz].second = h[1][i][j];
          sz ++;
        }
      }
      sort(pi, pi + sz);
      for(int i = 1; i < sz; i ++) {
        if(pi[i] == pi[i - 1]) return 1;
      }
      
      return 0;
    }
    
    int main() {
      init();
      b[0][0] = 1LL;
      b[1][0] = 1LL;
      for(int i = 1; i <= 250000; i ++) {
        b[0][i] = b[0][i - 1] * base[0] % mod[0];
        b[1][i] = b[1][i - 1] * base[1] % mod[1];
      }
      scanf("%d%d", &n, &m);
      for(int i = 0; i < n; i ++) {
        scanf("%s", s[i]);
      }
      int L = 1, R = min(n, m), ans = 0;
      while(L <= R) {
        int mid = (L + R) / 2;
        if(check(mid)) L = mid + 1, ans = mid;
        else R = mid - 1;
      }
      printf("%d
    ", ans);
      return 0;
    }
    
    /*
     
     5 10
     ljkfghdfas
     isdfjksiye
     pgljkijlgp
     eyisdafdsi
     lnpglkfkjl
     
     */
    
  • 相关阅读:
    SpringMVC+Apache Shiro+JPA(hibernate)
    Win7系统上配置使用Intellij Idea 13的SVN插件
    标志一个方法为过时方法
    Java模板引擎 HTTL
    Spring security与shiro
    墨刀 手机app原型工具
    java远程调试(断点)程序/tomcat( eclipse远程调试Tomcat方法)
    结合MongoDB开发LBS应用
    基于LBS的地理位置附近的搜索以及由近及远的排序
    discuz 发布分类信息,能不能设置单版块去掉“发帖子”(默认点发帖后为自定义的默认分类信息模版)
  • 原文地址:https://www.cnblogs.com/zufezzt/p/8351751.html
Copyright © 2011-2022 走看看