题意:输入字符矩阵,求最小的矩阵使复制很多次后的字符矩阵包含题目的矩阵。*不要理解成复制后等于题目的矩阵
解法:
对于行:求每行的可能循环,然后所有行共有的就是行的长度了,也就是列的数目了。
对于列:每行的字符串都求出来了,然KMP求出最小循环的行数
结果相乘就是答案。
备注:对于行来说,为什么不能向列一样求出最小的循环,参考此篇分析http://blog.sina.com.cn/s/blog_69c3f0410100tyjl.html,也就是找出最大的循环,对于其他行不一定成 立。
此次我也光荣的卡在了strcmp,也是基本上没怎么用过它,所以。。。若是小于的话输出负数,等于输出0,大于输出正数,就是这样。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <deque>
#define maxn 10005
#define ull unsigned long long
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
const ull inf = 1LL << 61;
using namespace std;
bool cmp(int a,int b){
return a>b;
}
int main()
{
//freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int r,c,i,j,k,n,m,getlen[100],next[maxn];
cin>>r>>c;
string s;
memset(next,-1,sizeof(next));
cle(getlen);
char str[maxn][100];
rep(i,r)
{
cin>>s;
int len=s.size();
rep(j,len)
{
str[i][j]=s[j];
}
for(j=len-1;j>=0;j--)//枚举循环长度
{
n=0;
for(k=j+1;k<c;k++)
{
if(k%(j+1)==0)//新一段的起点
{
n=0;
}
if(str[i][k]!=str[i][n])
{
break;
}
n++;
}
if(k==len)
{
getlen[j]++;
}
}
}
int ans1,ans2;
rep(i,c)
{
if(getlen[i]==r)
{
ans1=i;
break;
}
}
ans1++;
rep(i,r)
{
str[i][ans1]=0;
}
for(i=1;i<r;i++)
{
for(k=next[i-1];k>=0&&strcmp(str[k+1],str[i])!=0;k=next[k]);
if(strcmp(str[k+1],str[i])==0)next[i]=k+1;
}
cout<<((r-1-next[r-1]))*(ans1)<<endl;
return 0;
}