159. 奶牛矩阵 - AcWing题库
先找到每一行的最小循环节,再对每一行的一段字符串做kmp
#include <bits/stdc++.h>
#include <iostream>
#include<unordered_map>
#include<unordered_set>
#define x first
#define y second
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
typedef long long LL ;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<LL,int> PLI ;
const int N = 1e5+10 ;
const LL INF2 = 1e17;
int n,m;
char s[N][80];
int ne[80];
bool st[N];
inline void solve()
{
cin >> n >> m;
for(int i=1;i<=n; i++ )
{
cin >> s[i];
for(int j=1;j <= m;j ++ )
{
bool flag =1;
for(int k=j;k<m;k += j ) // 枚举每一段 长度为j的 的起点
{
for(int u=0;u < j && k + u < m ; u ++ )
if(s[i][u] != s[i][k + u ])// 两段内有一个地方不一样
{
flag =0 ;break;
}
if(!flag) break;
}
if(!flag) st[j] = 1;// 不存在j长度的循环节
}
}
int width;
for(int i=1;i<=m; i++ )if(!st[i]) { width = i;
break;}
for(int i=1;i<=n;i ++ ) s[i][width] = 0;//将每一行长度为width的一段 变成一个字符串 等于是末尾加了'\0'
// 对每一行做kmp
for(int i=2,j=0;i <= n;i ++ )
{
while(j && strcmp(s[j + 1 ] ,s[i])) j = ne[j];
if(!strcmp(s[j +1 ],s[i])) j ++ ;
ne[i] = j;
}
int height = n - ne[n];
cout << height * width << endl;
}
signed main()
{
ios
int T=1;
// cin>>T;
while(T -- )
{
solve();
}
return 0;
}