题意:给你一个字符矩阵,求出它的最小覆盖子矩阵,即使得这个子矩阵的无限复制扩张之后的矩阵,能包含原来的矩阵。 即二维的最小覆盖子串。
思路:KMP很好的一道题。首先易证:最小覆盖子矩阵一定靠左上角。那么,我们考虑求出每一行的最小重复串长度,所有行的最小重复串的长度的lcm就是最小重复子矩阵的宽。然后我们对列也做相同的操作。于是我们就可以求得最小重复子矩阵的大小了。(这里要注意一点:当所得的宽大于原来的宽时,就让等于原来的宽,长也如此)。算法实现:算法的核心在于高效的求出每一行和每一列的最小重复串,这个可以最原串做一次KMP中的get_next()。(注:以上部分为转载)
代码如下:
#include<iostream>
using namespace std;
const int rMax = 10002;
const int cMax = 77;
int row, col;
char map[rMax][cMax];
int get_next_c(int r)
{ // 对每一行求最小覆盖串。
int next[cMax], j=1, k=0;
next[0] = -1;
next[1]=0;
while(j< col)
{
if( map[r][j] == map[r][k])
{
next[j+1]=k+1;
j++;
k++;
}
else if (k==0)
{
next[j+1]=0;
j++;
}
else
k=next[k];
}
return j - next[j];
}
int get_next_r(int c)
{ // 对每一列求最小覆盖串。
int next[rMax], j=1, k=0;
next[0] = -1;
next[1]=0;
while(j< row)
{
if( map[j][c] == map[k][c])
{
next[j+1]=k+1;
j++;
k++;
}
else if (k==0)
{
next[j+1]=0;
j++;
}
else k= next[k];
}
return j- next[j];
}
int lcm(int a, int b)
{ // 求a,b的最小公倍数lcm。这个模板应该学。
int mul = a * b;
int r = a % b;
while(r)
{
a = b;
b = r;
r = a % b;
}
return mul / b; // 最小公倍数 * 最大公约数 = a * b。
}
int main()
{
int r, c, ans_r = 1, ans_c = 1;
scanf("%d%d", &row, &col);
for(r = 0; r < row; r ++) // 改逐个输入为逐行输入,从700MS优化到100MS,汗.....
scanf("%s", map[r]);
for(r = 0; r < row; r ++)
{
ans_c = lcm(ans_c, get_next_c(r));
if(ans_c > col)
{ // 注意! 当所得的宽大于原来的宽时,就让等于原来的宽,WA在了这里。
ans_c = col;
break;
}
}
for(c = 0; c < ans_c; c ++)
{
ans_r = lcm(ans_r, get_next_r(c));
if(ans_r > row)
{
ans_r = row;
break;
}
}
printf("%d\n", ans_r * ans_c);
return 0;
}
分享到:
相关推荐
提示:二叉树遍历而已,给出前序和中序,求后序 解题思路 1、前序遍历的第一个字母必是 根 2、在中序遍历的字母串中找出 根字母,那么根字母左右两边的字符串就分别是它的左、右子树 3、利用递归复原二叉树(把...
递归分形,java课程,一个小程序关于树形的动态演示。是两个源文件在一个.txt文件上需要重新复制黏贴建立两个java文件再使用。
POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类
poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题...
POJ第1861题源码 POJ第1861题源码 POJ第1861题源码
北大POJ1159-Palindrome 解题报告+AC代码
C语言 poj npu 西工大 C语言Poj答案全完整打包,给有需要的朋友
poj 3414解题报告poj 3414解题报告poj 3414解题报告poj 3414解题报告
poj分类poj分类poj分类poj分类
poj 1012解题报告poj 1012解题报告poj 1012解题报告poj 1012解题报告
poj 2329解题报告poj 2329解题报告poj 2329解题报告poj 2329解题报告
北大POJ2002-Squares 解题报告+AC代码
POJ1503解答 POJ1503解答,正确答案(已通过POJ)
poj 1659解题报告poj 1659解题报告poj 1659解题报告poj 1659解题报告
POJ1048,加强版的约瑟夫问题 难度中等
POJ1083的代码,POJ1083的代码,POJ1083的代码
poj 百练 题目分类 poj 百练 题目分类
POJ上的一道题目,自己写的代码,因为想下载别人的, 所以就放上了。
poj 1001答案
POJ2968代码有用,欢迎下载,POJ代码