POJ2185 Milking Grid 题解 KMP算法
题目链接:http://poj.org/problem?id=2185
题目大意:求一个二维的字符串矩阵的最小覆盖子矩阵,即这个最小覆盖子矩阵在二维空间上不断翻倍后能覆盖原始矩阵。
题目分析:next函数的应用。需要枚举每一行每一列的字符串所对应的的 \(nxt[]\) 值,然后通过分析计算出最小的宽和最小的高。
具体分析
参考链接:https://blog.csdn.net/u013686535/article/details/52197467
一看这题,容易想出一种很直观的做法:求出每一行的最小重复串长度,取所有行的最小重复串长度的lcm为宽;对列也同样操作求出高。这种想法虽然很直观,但是否正确呢?
事实上,这种算法并不是正确的。如下面的这个反例:
2 8
ABCDEFAB
AAAABAAA
对于这个例子:第一行为6,第二行为5,6与5的最小公倍数为30,大于8则取8为宽,但明显是错误的。
但由于poj的测试数据太弱,以致使用这种方法的程序也可以通过。
下面介绍一下正解的做法。
首先是确定宽度:我们分别求出每行所有可能的重复子串长度,例如对于aaaa就有1、2、3和4,然后取每行都有的重复子串长度中最小的作为宽。
例如,对于上面的例子,第一行的重复子串长度只可能是6或8(显然整个串为一个重复子串也是可以的),第二行则可能是5、6、7或8,那么取它们都有的6和8当中最小值6,就是最小覆盖子矩阵的宽。
然后分成两步:
- 考虑到每行的列数比较小, \(1 \le C \le 75\) ,可以直接暴力枚举重复子串的长度,每列逐一检查是否与当前枚举的重复子串相对应。因此求宽度这个部分的时间复杂度为 \(O(R \times C^2)\) 。
- 找到C以后我们再来一个个枚举R就可以了,时间复杂度也是 \(O(R \times C^2)\) 。
不过我这里采用标记的方式,时间复杂度降到 \(O(R \times C)\) 。
实现代码如下:
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 404000;
int m, nxt[maxn];
string t;
int N, M;
char ch[10010][80];
int cnt_c[80], cnt_r[10010];
void cal_next() {
m = t.length();
for (int i = 0, j = -1; i < m; i ++) {
while (j != -1 && t[j+1] != t[i]) j = nxt[j];
nxt[i] = (j+1 < i && t[j+1] == t[i]) ? ++j : -1;
}
}
void solve() {
// 首先清空用于记录的cnt_c和cnt_r数组
memset(cnt_c, 0 ,sizeof(cnt_c));
memset(cnt_r, 0, sizeof(cnt_r));
// 遍历每一行
for (int i = 0; i < N; i ++) {
t = "";
for (int j = 0; j < M; j ++) t += ch[i][j];
cal_next();
int j = m-1;
while (nxt[j] != -1) {
j = nxt[j];
cnt_c[m-1-j] ++;
}
}
// 遍历每一列
for (int i = 0; i < M; i ++) {
t = "";
for (int j = 0; j < N; j ++) t += ch[j][i];
cal_next();
int j = m-1;
while (nxt[j] != -1) {
j = nxt[j];
cnt_r[m-1-j] ++;
}
}
// 找到最小的cnt_c[i]==N,没有则M
int cc = 1, rr = 1;
for (; cc < M; cc ++) if (cnt_c[cc] == N) break;
// 找到最小的cnt_r[i]==M,没有则N
for (; rr < N; rr ++) if (cnt_r[rr] == M) break;
cout << rr * cc << endl;
}
int main() {
while (cin >> N >> M) {
for (int i = 0; i < N; i ++) cin >> ch[i];
solve();
}
return 0;
}
作者:zifeiy
POJ2185 Milking Grid 题解 KMP算法的更多相关文章
- poj2185 Milking Grid【KMP】
Milking Grid Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 10084 Accepted: 4371 Des ...
- POJ2185 Milking Grid 【lcm】【KMP】
Description Every morning when they are milked, the Farmer John's cows form a rectangular grid that ...
- POJ 2185 Milking Grid(KMP)
Milking Grid Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 4738 Accepted: 1978 Desc ...
- 【kmp算法】poj2185 Milking Grid
先对每行求出所有可能的循环节长度(不需要整除). 然后取在所有行中都出现了的,且最小的长度为宽. 然后将每一行看作字符,对所有行求next数组,将n-next[n](对这些行来说最小的循环节长度)作为 ...
- POJ2185 Milking Grid KMP两次(二维KMP)较难
http://poj.org/problem?id=2185 大概算是我学KMP简单题以来最废脑子的KMP题目了 , 当然细节并不是那么多 , 还是码起来很舒服的 , 题目中描写的平铺是那种瓷砖一 ...
- [USACO2003][poj2185]Milking Grid(kmp的next的应用)
题目:http://poj.org/problem?id=2185 题意:就是要求一个字符矩阵的最小覆盖矩阵,可以在末尾不完全重合(即在末尾只要求最小覆盖矩阵的前缀覆盖剩余的尾部就行了) 分析: 先看 ...
- POJ 2185 Milking Grid (KMP,求最小覆盖子矩阵,好题)
题意:给出一个大矩阵,求最小覆盖矩阵,大矩阵可由这个小矩阵拼成.(就如同拼磁砖,允许最后有残缺) 正确解法的参考链接:http://poj.org/showmessage?message_id=153 ...
- POJ3080 Blue Jeans 题解 KMP算法
题目链接:http://poj.org/problem?id=3080 题目大意:给你N个长度为60的字符串(N<=10),求他们的最长公共子串(长度>=3). 题目分析:KMP字符串匹配 ...
- HDU1711 Number Sequence 题解 KMP算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 题目大意:最基础的字符串匹配,只不过这里用整数数组代替了字符串. 给你两个数组 \(a[1..N ...
随机推荐
- JSON和JSONP,原来ajax引用这个来实现跨域访问的
由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socket通讯 ...
- python之pip
sudo vim /usr/bin/lsb_release 确保第一行是python2.7,不然无法使用pip安装第三方依赖
- golang之Sprintf函数
- mybatis官网文档mybatis_doc
在平时的学习中,我们可以去参考官网的文档来学习,这个文档有中文的,方便我们去阅读,而且这里的分类很详细. 官网文档链接:http://www.mybatis.org/mybatis-3/zh/inde ...
- dns-prefetch对网站速度能提升有多少?详解dns-prefetch。
DNS解析场景 有很多大型的网站,都会用N 个CDN 域名来做图片.静态文件等资源访问.比如新浪,我们经常会看到有下列域. img1.sina.com.cn . img2.sina.com.cn .i ...
- 从Docker容器内部,如何连接到本机的本地主机?
原文 从Docker容器内部,如何连接到本机的本地主机? 编辑:如果您使用的是Docker-for-mac或Docker-for-Windows 18.03+,只需使用主机连接到您的mysql服务即可 ...
- Leetcode695.Max Area of Island岛屿的最大面积
给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合.你可以假设二维矩阵的四个边缘都被水包围着. 找到给定的二维数组中 ...
- Directx11教程(62) tessellation学习(4)
原文:Directx11教程(62) tessellation学习(4) 现在看看四边形在不同tess factor时,四边形细分的细节,下图是tess factor1-8时候的细分.te ...
- 2018-2-13-图论-Warshall-和Floyd-矩阵传递闭包
title author date CreateTime categories 图论 Warshall 和Floyd 矩阵传递闭包 lindexi 2018-2-13 17:23:3 +0800 20 ...
- 【风马一族_php】常用的语句
设置脚本的编码 <?php header('Content-type:text/html;charset=utf-8'); ?> 按原格式的输入内容 echo <pre>; ...