【牛客 -2A】矩阵(二分,字符串哈希)
题干:
给出一个n * m的矩阵。让你从中发现一个最大的正方形。使得这样子的正方形在矩阵中出现了至少两次。输出最大正方形的边长。
输入描述:
第一行两个整数n, m代表矩阵的长和宽;
接下来n行,每行m个字符(小写字母),表示矩阵;
输出描述:
输出一个整数表示满足条件的最大正方形的边长。
示例1
输入
复制
5 10
ljkfghdfas
isdfjksiye
pgljkijlgp
eyisdafdsi
lnpglkfkjl
输出
复制
3
备注:
对于30%的数据,n,m≤100;
对于100%的数据,n,m≤500;
解题报告:
二分一下矩阵的边长,然后用字符串哈希判断两个矩阵是否相同就可以,,网络上找到一个map的解法,,但是感觉时间复杂度太不稳定,好的时候700ms,差的时候超时,,于是还是以后用多项式哈希吧。。这两个刚学哈希,,代码还是不特别美观、、
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 505;
using namespace std;
const ll D1=31,D2=131;
int n,m;
char a[MAX][MAX];
ull pow1[MAX],pow2[MAX],h[MAX][MAX],tmp,tmp2,Hash[MAX*MAX];
bool ok(int x) {memset(h,0,sizeof h);int tot=0;for(int i = 1; i<=n; i++) {ull tmp = 0;for(int j = 1; j<x; j++) h[i][j] = h[i][j-1] * D1 + a[i][j];for(int j = x; j<=m; j++) h[i][j] = h[i][j-1] * D1 + a[i][j] - pow1[x] * a[i][j-x];
// for(int j = 1; j<x; j++) tmp = tmp * D1 + a[i][j];
// for(int j = x; j<=m; j++) h[i][j] = tmp * D1 + a[i][j] - pow1[x] * a[i][j-x] , tmp = h[i][j];}for(int j = x; j<=m; j++) {ull tmp = 0;for(int i = 1; i<x; i++) tmp = tmp*D2 + h[i][j];for(int i = x; i<=n; i++) Hash[++tot] = tmp*D2 + h[i][j] - pow2[x] * h[i-x][j] , tmp = Hash[tot];}sort(Hash+1,Hash+tot+1);for(int i = 1; i<tot; i++) {if(Hash[i] == Hash[i+1]) return 1;}return 0 ;
}
int main()
{
// ull qq=1,ww=2;
// cout <<qq-ww;scanf("%d%d",&n,&m);for(int i=1; i<=n; i++) {scanf("%s",a[i]+1);for(int j=1; j<=m; j++) {a[i][j]-=('a'-1);}}int l=1,r=min(n,m);int mid = (l+r)>>1;int ans;pow1[0]=pow2[0]=1;for(int i=1; i<=n; i++) pow1[i]=pow1[i-1]*D1;for(int i=1; i<=m; i++) pow2[i]=pow2[i-1]*D2;while(l<=r) {mid=(l+r)>>1;if(ok(mid)) l=mid+1,ans=mid;else r=mid-1; }printf("%d",ans);return 0;
}
AC代码2:(map版)(这个时不时会跑个超时、。。)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
using namespace std;
typedef unsigned long long ull;
typedef pair<int,int>P;
#define maxn 505
int n,m;
char s[maxn][maxn];
ull h[maxn][maxn],b[maxn*maxn],base=10007,hhh[maxn][maxn];
inline int ID(int i,int j) {return (i-1)*m+j;
}
inline bool check(int mid) {map<ull,int>M;for(int x=1; x<=n-mid+1; x++)for(int y=1; y<=m-mid+1; y++) {int xx=x+mid-1,yy=y+mid-1;ull val=(h[xx][yy]-h[xx][y-1]-h[x-1][yy]+h[x-1][y-1])*b[(n-x)*m+m-y];if(M.find(val)!=M.end())return 1;M[val]=1;}return 0;
}
int main() {scanf("%d%d",&n,&m);for(int i=1; i<=n; i++)scanf("%s",s[i]+1);b[0]=1;for(int i=1; i<=n; i++)for(int j=1; j<=m; j++) {h[i][j]=h[i][j-1]+b[ID(i,j-1)]*(s[i][j]-'a');b[ID(i,j)]=b[ID(i,j-1)]*base;}
// for(int j=1; j<=m; j++)
// for(int i=1; i<=n; i++)
// h[i][j]+=h[i-1][j];int l=0,r=min(n,m),mid,ans=0;while(l<=r) {mid=(l+r)/2;if(check(mid))ans=mid,l=mid+1;else r=mid-1;}printf("%d\n",ans);return 0;
}
总结:据syt表示,哈希题目多半带个log,,这次做题果然是,需要比较,所以需要先排序这样。
【牛客 -2A】矩阵(二分,字符串哈希)相关推荐
- 牛客题霸 [将字符串转化为整数] C++题解/答案
牛客题霸 [将字符串转化为整数] C++题解/答案 题目描述 实现函数 atoi .函数的功能为将字符串转化为整数 提示:仔细思考所有可能的输入情况.这个问题没有给出输入的限制,你需要自己考虑所有可能 ...
- 牛客题霸 [找到字符串的最长无重复字符子串] C++题解/答案
牛客题霸 [找到字符串的最长无重复字符子串] C++题解/答案 题目描述 给定一个数组arr,返回arr的最长无的重复子串的长度(无重复指的是所有数字都不相同). 题解: i和j两个指针分别指不重复子 ...
- 牛客题霸 [反转字符串] C++题解/答案
牛客题霸 [反转字符串] C++题解/答案 题目描述 写出一个程序,接受一个字符串,然后输出该字符串反转后的字符串.(字符串长度不超过1000) 题解: 有reverse现成的翻转函数,直接套进去就可 ...
- 牛客题霸 [旋转字符串]C++题解/答案
牛客题霸 [旋转字符串]C++题解/答案 题目描述 字符串旋转: 给定两字符串A和B,如果能将A从中间某个位置分割为左右两部分字符串(都不为空串),并将左边的字符串移动到右边字符串后面组成新的字符串可 ...
- 牛客题霸 二分查找 C++题解/答案
牛客题霸 二分查找 C++题解/答案 题目描述 请实现有重复数字的有序数组的二分查找. 输出在数组中第一个大于等于查找值的位置,如果数组中不存在这样的数,则输出数组长度加一. 示例1 输入 复制 5, ...
- 牛客网——矩阵相等判定
活动地址:CSDN21天学习挑战赛 目录 前言 一.矩阵相等判断 描述 输入描述: 输出描述: 二.代码如下 总结 前言 今天和大家一起学习一下,矩阵相等判定. 一.矩阵相等判断 题目来源: 矩阵相等 ...
- 【牛客】CSL 的字符串 (stack map)
https://ac.nowcoder.com/acm/contest/551/D 这个题怎么说,data用来存储这个字母在字符串中最后一次出现的位置,vis则用来记录该字母是否在栈中. 当栈为空的时 ...
- 牛客练习赛42 A 字符串
题目描述 给定两个等长的由小写字母构成的串 A,BA,B,其中 |A|=|B|=n|A|=|B|=n. 现在你需要求出一个子区间 [l,r][l,r] 使得 LCP(A[l,r],B[l,r])×LC ...
- 牛客多校6 - K-Bag(哈希+滑动窗口)
题目链接:点击查看 题目大意:k-bag 序列的定义是由多个 1 ~ k 的排列顺序连接起来的序列,现在问给定的序列是不是 k-bag 的连续子串 题目分析:读完题目后,如果给定的序列是 k-bag ...
最新文章
- IDEA2020如何设置全局maven路径
- python信号与槽_Python信号和插槽(1),python,与,一
- Nginx报错request entity too large的解决方案
- springboot+shiro+redis项目整合
- linux一步一脚印---more、less、head、tail
- 关于常用的git命令列表
- C-free在编写代码的过程中遇到方向键失灵,回车键失灵,换行失灵,但是可以正常输入的解决办法!!!!!
- phpthink验证旧密码_忘记MacBook密码解决方法
- 实验2.3 使用重载函数模板重新实现上小题中的函数Max1
- 自然语言处理在金融实时事件监测和财务快讯中的应用
- 【前端知识梳理】HTML篇 笔记整理(一)
- Unity之FBX文件操作学习笔记(二)SDK sample代码初探
- matlab中polyfit和polyval的使用(曲线拟合/多项式拟合/指数拟合)
- java 熄灯问题_C++基础算法学习——熄灯问题
- 老中医治蛋变成绿色了
- 基于JAVA医院预约挂号系统设计与实现 开题报告
- 后台清理 清理cookie_清理枯木
- sql 查询之排除某种特定的数据
- LIO-SAM imuPreintegration
- HCL实验-使用ACL进行SSH服务器的登录源限制的简单实验(NAT+SSH+ACL)
热门文章
- 15. 3Sum-数组
- 【数据结构与算法】快排、归并 O(nlogn) 基于比较
- notion函数_Notion使用指南 | Database篇
- python查找两个数组中相同的元素_匹配两个numpy数组以找到相同的元素
- 获取apk安装包sha1的值
- python pp模块_python常用模块
- 左右伸缩_冬季装修为啥要留伸缩缝?等到天热地板开裂就晚了!合肥人注意下...
- python人工智能原理及其应用_人工智能原理与实践:基于Python语言和TensorFlow
- 零基础Unreal Engine 4(UE4)图文笔记之粒子系统
- 直连串口线、交叉串口线