URAL 1486(二维字符串hash)
来源:互联网 发布:刚性攻丝编程 编辑:程序博客网 时间:2024/05/21 20:26
题意:一个最大500*500的字符矩阵,求最大的两个相同的字符正方形。正方形可以有重叠部分但不能重合。
解法:首先是二分正方形的长度,然后判断某个长度存在时候计算字符矩阵的二维hash值,二维hash的方法是:
这样子拓展的hash算法可以O(1) 获取任意一个子矩阵的hash值。
代码:
/******************************************************* @author:xiefubao*******************************************************/#pragma comment(linker, "/STACK:102400000,102400000")#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <vector>#include <algorithm>#include <cmath>#include <map>#include <set>#include <stack>#include <string.h>//freopen ("in.txt" , "r" , stdin);using namespace std;#define eps 1e-8#define zero(_) (abs(_)<=eps)const double pi=acos(-1.0);typedef unsigned long long LL;const int Max=502;const LL INF=100007;char s[Max][Max];LL hash[Max][Max];LL hash2[Max][Max];LL scale[Max];LL scale2[Max];LL seed=3131;LL seed2=1313;int n,m;int count1=0;struct edge{ LL data; int next; int x,y;} edges[Max*Max];int head[100010];int tot=0;void add(LL u,LL data,int x,int y){ edges[tot].data=data; edges[tot].x=x; edges[tot].y=y; edges[tot].next=head[u]; head[u]=tot++;}int have(LL value){ LL t=value%INF; for(int i=head[t];i!=-1;i=edges[i].next) { if(edges[i].data==value) return i+1; } return 0;}bool OK(int t){ memset(head,-1,sizeof head); tot=0; for(int i=1; i+t-1<=n; i++) for(int j=1; j+t-1<=m; j++) { LL value=0; value=hash2[i+t-1][j+t-1]-hash2[i+t-1][j-1]*scale[t]-hash2[i-1][j+t-1]*scale2[t]+hash2[i-1][j-1]*scale[t]*scale2[t]; if(have(value)) return true; add(value%INF,value,i,j); } return false;}void solve(int t){ memset(head,-1,sizeof head); tot=0; for(int i=1; i+t<=n+1; i++) for(int j=1; j+t<=m+1; j++) { LL value=0; value=hash2[i+t-1][j+t-1]-hash2[i+t-1][j-1]*scale[t]-hash2[i-1][j+t-1]*scale2[t]+hash2[i-1][j-1]*scale[t]*scale2[t]; int ok=have(value); if(ok) { cout<<edges[ok-1].x<<" "<<edges[ok-1].y<<endl; cout<<i<<" "<<j<<endl; return ; } else add(value%INF,value,i,j); }}int main(){ while(cin>>n>>m) { scale[0]=1; scale2[0]=1; for(int i=1; i<Max; i++) scale[i]=scale[i-1]*seed,scale2[i]=scale2[i-1]*seed2; for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) cin>>s[i][j]; for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) { hash[i][j]=hash[i][j-1]*seed+s[i][j]; hash2[i][j]=hash2[i-1][j]*seed2+hash[i][j]; } int left=1; int right= n==m?n-1:min(n,m); while(left<=right) { int middle=(left+right)/2; if(OK(middle)) left=middle+1; else right=middle-1; } if(right==0) cout<<right<<endl; else { cout<<right<<endl; solve(right); } } return 0;}
0 0
- URAL 1486(二维字符串hash)
- URAL 1486 Equal Squares 二维字符串Hash + 邻接表分组
- 字符串hash(二维)-poj3690
- URAL 1989 Subpalindromes(字符串HASH&线段树单点更新)
- URAL 1989 Subpalindromes(线段树单点修改+字符串hash)
- Ural 1486. Equal Squares 字符串hash
- POJ 3690 字符串的二维hash
- ural Bicolored Horses(二维dp)
- URAL 1585. Penguins (字符串)
- ural 1613【hash+二分】
- HOJ 13383 The Big Painting 二维字符串hash
- poj2503(字符串hash)
- Tyvj1057(字符串hash)
- poj1733 & Ural 1003 Parity Game (hash+并查集 )
- URAL 1989 Subpalindromes(回文串 线段树 多项式hash)
- bzoj 2351: [BeiJing2011]Matrix(二维Hash)
- ural 1052. Rabbit Hunt hash
- URAL 1612. Tram Forum(字符串啊 )
- PopupWindow和AlertDialog区别
- begining for my weibo life
- Flex 简单的DataGrid 例子
- marine plywood and brown brown film faced plywood pvxl
- Java中String和String Buffer两种字符串类型之间的区别和联系
- URAL 1486(二维字符串hash)
- sku过滤,判断提交过来的sku和完成sku数组比对
- ESXi5.1物理主机root用户密码的破解方法(一)
- 链表的常见操作
- struts2核心
- 新入手SSD,不想重新安装系统,怎么破
- HttpClient4.3教程(转载)
- Java 中的语法糖 (Syntactic Sugar)
- CoreData 怎么在viewControl中使用。