poj2185Milking Grid【kmp next数组求循环节】
2015-08-27 16:10
483 查看
大意:告诉你一个字符矩阵 然后让你找出一个最小的矩阵 整个矩阵能用该小矩阵去填充, 可以超出边界
例如:
ABABABA
ABABABA
可以用AB去铺满
最后一列A用AB填充 超出边界部分就忽略
分析:
把整个矩阵先按行来看
求出每行字符串的最小循环节 也就是l - next[l]
然后求出他们的最小公倍数 也就是公共的最小循环节 注意要把该倍数与边界作比较 取小值
通过以上 就能求出 用n行用最小公倍数列做区间能把后面几列铺完
用同样的方法对1~最小公倍数列进行求解
代码:
View Code
例如:
ABABABA
ABABABA
可以用AB去铺满
最后一列A用AB填充 超出边界部分就忽略
分析:
把整个矩阵先按行来看
求出每行字符串的最小循环节 也就是l - next[l]
然后求出他们的最小公倍数 也就是公共的最小循环节 注意要把该倍数与边界作比较 取小值
通过以上 就能求出 用n行用最小公倍数列做区间能把后面几列铺完
用同样的方法对1~最小公倍数列进行求解
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; void Get(char *s, int *next) { int l = strlen(s); int j = 0, k = -1; next[0] = -1; while(j < l) { if(k == -1 || s[j] == s[k]) { next[++j] = ++k; } else { k = next[k]; } } } const int maxn = 10005; int next[maxn]; int Circle(char *s) { Get(s, next); int l = strlen(s); return l - next[l]; } char s[maxn][maxn]; char s2[maxn][maxn]; int main() { int n, m; while(EOF != scanf("%d %d",&n, &m) ) { for(int i = 0; i < n; i++) { scanf("\n%s", s[i]); } for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { s2[j][i] = s[i][j]; } } int ans = 1; for(int i = 0; i < n; i++) { int x = Circle(s[i]); int y = __gcd(ans, x); ans = ans * x / y; } if(ans > m) ans = m; int sum = 1; for(int i = 0; i < ans; i++) { int x = Circle(s2[i]); int y = __gcd(sum, x); sum = sum * x / y; } if(sum > n) sum = n; printf("%d\n", ans * sum); } }
View Code
相关文章推荐
- 凸优化和非凸优化
- Postgresql自增
- Aspose.Words如何重命名合并字段
- Centos系统更改 yum源为163
- 树的子结构
- 响应式图片的3种解决方案
- Linux安装软件总结 (一.安装方法介绍)
- 纯CSS3实现飘逸洒脱带有飞行效果的三级下拉菜单
- 抽取任意层特征---caffe使用MemoryDataLayer从内存中加载数据
- devstack nova-docker local.conf
- 损失函数(loss function)
- DOM对象
- [LeetCode] Maximal Rectangle(!!!DP)
- EqualizeHist函数
- Keychain
- 关于PLSA的一个参数公式的解释
- db.class的实现类
- Gif多图:我常用的 16 个 Sublime Text 快捷键
- Ehcache 分布式缓存 -springMVC
- 11. jQuery - Chaining