题意:就是让你求出最小的字符矩阵面积,这个矩阵是这个大矩阵里能够循环的,但是并不一定是全部循环相同的,部分相同也算循环,比如样例。
思路:这题挺好的,以前没有想到二维字符串数组也可以用next数组求出其循环节,现在这题正好补了这个空。
解法:把每一个字符串当做字符进行求next数组,然后求出最小的循环字符串长度,即:len-next[len]。因为以前求循环节是len/(len-next[len]),括号里面的不就是最小的循环长度嘛!
因为要求这个循环矩阵的长和宽,所以长就是每一行作为一个字符串,然后求出最小循环字符串长度;宽就是每一列作为一个字符串,也求出循环长度,相乘即为答案!
刚开始看网上好多代码没看懂,什么最公倍数啊最小覆盖啊,都没看懂博主在干嘛,其实好理很解的嘛二维KMP。上面解释也很清楚了,还不理解的看代码就懂了。
#pragma comment(linker, "/STACK:1024000000,1024000000")//扩内存,因为有的题目可能要开1000*1000的数组 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<queue> #include<set> #include<cmath> #include<bitset> #define mem(a,b) memset(a,b,sizeof(a)) #define lson i<<1,l,mid #define rson i<<1|1,mid+1,r #define llson j<<1,l,mid #define rrson j<<1|1,mid+1,r #define INF 6 #define maxn 10005 typedef long long ll; typedef unsigned long long ull; using namespace std; int next[maxn]; char s[maxn][maxn],str[77][maxn],ss[maxn]; int getnext(int len,char p[][maxn]) { int i,j; mem(next,0); next[0]=next[1]=0; for(i=1;i<len;i++) { j=next[i]; while(j&&strcmp(p[i],p[j])) j=next[j]; next[i+1]=(!strcmp(p[i],p[j])?j+1:0); } return len-next[len]; } int main() { //freopen("1.txt","r",stdin); int l,r,i,j; scanf("%d%d",&l,&r); for(i=0;i<l;i++) scanf("%s",s[i]); for(i=0;i<r;i++) for(j=0;j<l;j++) str[i][j]=s[j][i];//取出每一列作为新的字符串,因为宏观上要求列的循环长度 int w=getnext(l,s);//宽 int h=getnext(r,str);//长 printf("%d\n",w*h); return 0; }
POJ 2185 二维KMP
时间: 2024-10-13 07:03:16