• POJ 2185


    题目链接:

      http://poj.org/problem?id=2185

    题目描述:

      给定一个R * C的矩阵,在该矩阵中寻找一个子矩阵,要求子矩阵复制多次能够包含原矩阵。

    解题思路:

      如果在字符串中找到一个最小子串使其复制多次包含原字符串,那么我们可以很容易想到通过kmp算法的next数组来得出该子串长度,即len - next[len]。

      那么回到这道题,要在矩阵中找到合法的最小子矩阵,其实跟找最小子串的原理是一样的,只需要对矩阵的行和列分别看成一个字符串用kmp算法过一遍,然后分别得到一个最小行数,该行数复制多遍可以包含原矩阵,以及一个最小列数,该列数复制多遍同样可以包含原矩阵,那么题目要求的子矩阵宽和高就这样得到了,最后相乘一下输出就搞定啦。

    代码:

     1 #include <iostream>
     2 #include <cmath>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <map>
     6 #include <vector>
     7 #include <algorithm>
     8 using namespace std;
     9 
    10 #define ll long long
    11 #define INF 0x3f3f3f3f3f
    12 #define MAX 
    13 
    14 char rectangle[10010][100];
    15 int fail[10010];
    16 int R, C;
    17 
    18 /*
    19 判断矩阵行与行之间是否相等
    20  */
    21 bool cmp1(int j, int k)
    22 {
    23     for(int i = 0; i < C; ++i) {
    24         if(rectangle[j][i] != rectangle[k][i])
    25             return 0;
    26     }
    27     return 1;
    28 }
    29 
    30 /*
    31 判断矩阵列与列之间是否相等
    32  */
    33 bool cmp2(int j, int k)
    34 {
    35     for(int i = 0; i < R; ++i) {
    36         if(rectangle[i][j] != rectangle[i][k])
    37             return 0;
    38     }
    39     return 1;
    40 }
    41 
    42 int main()
    43 {
    44     //freopen("debug\in.txt", "r", stdin);
    45     //freopen("CON", "w", stdout);
    46     int i, j, k;
    47     scanf("%d%d", &R, &C);
    48     for(i = 0; i < R; ++i) {
    49         scanf("%s", rectangle[i]);
    50     }
    51     fail[0] = k = -1;
    52     j = 0;
    53     //kmp获取next数组的超简洁版写法
    54     while(j < R) {
    55         while(k != -1 && !cmp1(j, k)) k = fail[k];
    56         fail[++j] = ++k;
    57     }
    58     int ans1 = R - fail[R]; //获得子矩阵高
    59     fail[0] = k = -1;
    60     j = 0;
    61     while(j < C) {
    62         while(k != -1 && !cmp2(j, k)) k = fail[k];
    63         fail[++j] = ++k;
    64     }
    65     int ans2 = C - fail[C]; //获得子矩阵宽
    66     printf("%d
    ", ans1 * ans2);
    67     return 068 }
  • 相关阅读:
    *HDU 1392 计算几何
    *HDU 1115 计算几何
    *HDU 1086 计算几何
    *HDU 2108 计算几何
    HDU 1528 贪心模拟/二分图
    HDU 1281 二分图
    *HDU1150 二分图
    *HDU1151 二分图
    *HDU 1068 二分图
    *HDU 1054 二分图
  • 原文地址:https://www.cnblogs.com/lc520love/p/5305870.html
Copyright © 2020-2023  润新知