poj2185(kmp)

题目链接: http://poj.org/problem?id=2185

 

题意: 给出一个矩形字符块, 求能组成该矩形块的最小子矩形块.

 

思路: 将每行字符串当作一个字符,那么原矩形字符块就成了一列字符,其最小循环节即为所求矩形块的宽;

将每列字符串当作一个字符,那么原矩形字符块就成了一行字符,其最小循环节即为所求矩形的长.

 

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 using namespace std;
 4 
 5 const int MAXN = 1e5 + 10;
 6 int nxt1[MAXN], nxt2[80];
 7 char str[MAXN][80];
 8 int n, m;
 9 
10 bool equal1(int x, int y){//判断两行字符串是否相等
11     for(int i = 0; i < m; i++){
12         if(str[x][i] != str[y][i]) return false;
13     }
14     return true;
15 }
16 
17 bool equal2(int x, int y){//判断两列字符串是否相等
18     for(int i = 0; i < n; i++){
19         if(str[i][x] != str[i][y]) return false;
20     }
21     return true;
22 }
23 
24 void get_nxt1(void){ //将每行字符串当作一个字符,求矩形字符块变成字符串后的nxt数组
25     int i = 0, j = -1;
26     nxt1[0] = -1;
27     while(i < n){
28         if(j == -1 || equal1(i, j)) nxt1[++i] = ++j;
29         else j = nxt1[j];
30     }
31 }
32 
33 void get_nxt2(void){ //将每列字符串当作一个字符,求矩形字符块变成字符串后的nxt数组
34     int i = 0, j = -1;
35     nxt2[0] = -1;
36     while(i < m){
37         if(j == -1 || equal2(i, j)) nxt2[++i] = ++j;
38         else j = nxt2[j];
39     }
40 }
41 
42 int main(void){
43     scanf("%d%d", &n, &m);
44     for(int i = 0; i < n; i++){
45         scanf("%s", str[i]);
46     }
47     get_nxt1();
48     get_nxt2();
49     int cnt1 = n - nxt1[n];
50     int cnt2 = m - nxt2[m];
51     printf("%d\n", cnt1 * cnt2);
52     return 0;
53 }
View Code

 

posted @ 2017-08-12 21:31  geloutingyu  阅读(463)  评论(0编辑  收藏  举报