SPOJ - PLSQUARE Palin Squar(hash+回文串)
题意:给你一个n*n (n<=200)的字符串矩阵,问你每行每列都是回文串的最大的m*m的矩阵是多少
题解:首先答案不满足单调性,即m成立而m-1与m+1都却不一定成立,所以必须枚举答案确定现在的值是否成立,从大到小枚举就好
当枚举值为k时就转换为判断k是否为所求矩阵,判断时我们需要枚举每个点,(看从这个点开始是否向右向下都有连续k个回文串)
而我们可以分别找向右和向下,标记这个点向右或向下是否满足(从这个点开始是否向右向下都有连续k个回文串)
我们找向下时枚举每列每个向右k个字符是否为回文串
如果这个是回文,就在基础上加一否则基础就变成0(连续断掉),接着马上判断基础,大于k就在此位置前面k-1个位置标记为1
时间复杂度就是O(n^3),乘上前面的O(n)就过不了,但是我们可以预处理每个点向右,向下每个长度是否为回文串,这样就可以降O(n)的时间复杂度
预处理可以使用hash就是经典用法。但是一个更简单的方法就是dp,因为我们要找每段,则可以递归
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=<<;
const ll INF=1ll<<;
const double Pi=acos(-1.0);
const int Mod=1e9+;
const int Max=;
const ull seed=1313ull;
ull base[Max],hashh[][Max];//求字符串hash值(前缀与后缀)
bool vis[][Max][Max];//固定答案时保存是否为回文
bool pal[Max][Max][][Max];//每个位置向左与向下每个长度是否为回文串
char str[Max][Max];
void Init(int n)
{
base[]=1ull;
for(int i=; i<n; ++i)
{
base[i]=base[i-]*seed;
}
return;
}
void InitPal(int n)
{
memset(pal,,sizeof(pal));
for(int i=; i<=n; ++i) //处理每个点的pal
{
for(int j=; j<=n; ++j)
{
hashh[][j-]=hashh[][j-]=0ull;
for(int k=j; k<=n; ++k)
{
hashh[][k]=hashh[][k-]*seed+(str[i][k]-'a'+1ull);
hashh[][k]=hashh[][k-]+(str[i][k]-'a'+1ull)*base[k-j];//后缀的hash
if(hashh[][k]==hashh[][k])
pal[i][j][][k-j+]=;//第i行第j个向右k-j个是否为回文串
//printf("%d ",pal[i][j][0][k-j+1]);
}
hashh[][i-]=hashh[][i-]=0ull;
for(int k=i; k<=n; ++k)
{
hashh[][k]=hashh[][k-]*seed+(str[k][j]-'a'+1ull);
hashh[][k]=hashh[][k-]+(str[k][j]-'a'+1ull)*base[k-i];//后缀的hash
if(hashh[][k]==hashh[][k])
pal[i][j][][k-i+]=;//第i行第j个向下k-j个是否为回文串
//printf("%d ",pal[i][j][1][k-i+1]);
}
//printf("\n");
}
}
}
int Jud(int ans,int n)//判断结果
{
memset(vis,,sizeof(vis));
for(int i=;i<=n;++i)//水平向右需要的是向下的回文串
{
int lev=,ver=;
for(int j=;j<=n;++j)
{
lev++;
if(!pal[i][j][][ans])//断开了
{
lev=;
}
if(lev>=ans)//此点左边ans个向下都是回文串
{
vis[][i][j-ans+]=;
} ver++;
if(!pal[j][i][][ans])//断开了
{
ver=;
}
if(ver>=ans)//此点下边ans个向右都是回文串
{
vis[][j-ans+][i]=;
}
}
}
for(int i=;i<=n;++i)
{
for(int j=;j<=n;++j)
{
if(vis[][i][j]&vis[][i][j])
return ;
}
}
return ;
}
int Solve(int n)
{
for(int i=n; i>; --i)//枚举结果
{
if(Jud(i,n))
return i;
}
return ;
}
int main()
{
Init(Max);
int n;
while(~scanf("%d",&n))
{
for(int i=; i<=n; ++i)
{
scanf("%s",str[i]+);
str[i][]='A';
}
InitPal(n);//初始化每个点向右玉向下每个位置是否为回文串
printf("%d\n",Solve(n));
}
return ;
}
SPOJ - PLSQUARE Palin Squar(hash+回文串)的更多相关文章
- bzoj 2124 等差子序列 树状数组维护hash+回文串
等差子序列 Time Limit: 3 Sec Memory Limit: 259 MBSubmit: 1919 Solved: 713[Submit][Status][Discuss] Desc ...
- bzoj 3768: spoj 4660 Binary palindrome二进制回文串
Description 给定k个长度不超过L的01串,求有多少长度为n的01串S满足: 1.该串是回文串 2.该串不存在两个不重叠的子串,在给定的k个串中. 即不存在a<=b<c<= ...
- bzoj 3676 回文串 manachar+hash
考虑每个回文串,它一定是它中心字母的最长回文串两侧去掉同样数量的字符后的一个子串. 所以我们可以用manachar求出每一位的回文半径,放到哈希表里并标记出它的下一个子串. 最后拓扑排序递推就行了.. ...
- Gym - 100570E:Palindrome Query (hash+BIT+二分维护回文串长度)
题意:给定字符串char[],以及Q个操作,操作有三种: 1:pos,chr:把pos位置的字符改为chr 2:pos:问以pos为中心的回文串长度为多长. 3:pos:问以pos,pos+1为中心的 ...
- SPOJ STC02 - Antisymmetry(Manacher算法求回文串数)
http://www.spoj.com/problems/STC02/en/ 题意:给出一个长度为n的字符串,问其中有多少个子串s可以使得s = s按位取反+翻转. 例如样例:11001011. 10 ...
- LOJ 2452 对称 Antisymmetry——用hash求回文串数
概念 用hash求最长回文串/回文串数 首先,易知,回文串具有单调性. 如果字符串 $s[l...r]$ 为回文串串,那么 $s[x...y]$($l < x, y < r$ 且 $|l- ...
- [CSP-S模拟测试]:回文串(hash+二分)
题目描述 $ASDFZ$的机房中不仅有红太阳,还有蓝太阳和原谅色太阳.有一天,太阳们来到机房,发现桌上有不知道哪个蒟蒻放上的问题:令$F(A,B)$表示选择一个串$A$的非空前缀$S$和串$B$的非空 ...
- CF452F等差子序列 & 线段树+hash查询区间是否为回文串
记录一下一个新学的线段树基础trick(真就小学生trick呗) 给你一个1到n的排列,你需要判断该排列内部是否存在一个3个元素的子序列(可以不连续),使得这个子序列是等差序列.\(n\) <= ...
- POWEROJ 2610 判断回文串 【HASH】
题目链接[https://www.oj.swust.edu.cn/problem/show/2610] 题意:给你一个字符串,让你判断这个字符串是不是回文串,字符串的长度是1<len<1e ...
随机推荐
- Fedora20-32bit cross-compiling arm-linux-gcc4.3.2
目录 0 前言 1 安装arm-linux-gcc-4.3.2 2 配置 nfs 服务器 0 前言 之前在 fedora 64bit 上建立交叉编译,但由于4.4.3版本需要另装用于gdb-serve ...
- 解决jeecg包升级之后无法启动的问题
1.出现下述问题的解决办法. 解决包冲突问题,右键项目,选择properties 把lib目录下的jar吧添加上.remove调版本较低的包即可. 2. 解决方法,把jdk升级到1.7版本
- web app开发利器 - iscroll4 解决方案
存在即是道理,iscroll会诞生,主要是因为无论是在iphone.ipod.android 或是更早前的移动webkit都没有提供一种原生的方式来支持在一个固定高度的容器内滚动内容, 这个不幸的规则 ...
- Boost正则表达式的编译与使用方法集
下载boost 在boost官网上下载任何版本都可以www.boost.org . 将boost压缩包解压到D盘目录下 (我下载的是boost_1_54_0.zip),目录为D:\boost_1_54 ...
- mysql 目录的了解以及Linux
Linux 目录 描述 / ...
- dom解析和sax解析的区别及优缺点
dom解析一开始就将文档所有内容装入内存,每个元素(标签)都作为一个element对象存储,形成对象树,缺点是对内存占用大,不能解析数据量很大的文档:优点是方便进行crud操作. sax解析,逐行解析 ...
- javascript实用技巧、javascript高级技巧
字号+作者:H5之家 来源:H5之家 2016-10-31 11:00 我要评论( ) 三零网提供网络编程. JavaScript 的技术文章javascript实用技巧.javascript高级技巧 ...
- flexbox学习
https://philipwalton.github.io/solved-by-flexbox/ http://www.ruanyifeng.com/blog/2015/07/flex-gramma ...
- bootstrap validate 实现页面动态验证(formvalidate)
关于基本的bootstrap validate 验证方法外面有许多博客上都有讲解,我就不在过多叙述了.大家也可以去看官网api:http://bv.doc.javake.cn/api/ 今天要说的是动 ...
- GitHub for Windows呆瓜级操作1
如何安装.注册.创建仓库等操作请参考http://www.cnblogs.com/foreveryt/p/4077380.html 1.点击右上角+号创建本地新仓库LHJ.点击Create repos ...