【大渣】【多维KMP】奶牛阵列
来源:互联网 发布:淘宝如何修改收货地址 编辑:程序博客网 时间:2024/05/16 19:04
奶牛阵列
Time Limit:10000MS Memory Limit:65536K
Total Submit:26 Accepted:18
Case Time Limit:1000MS
Description
每天早晨约翰的奶牛都会在挤奶的时候排成阵列,即站成R(1<=R<=10000)行C(1<=C<=75)列的矩阵。我们知道,约翰是奶牛专家,他打算写一本关于喂养奶牛的书,他发现,当奶牛按不同血统标记以后,整个大矩阵就像由很多小矩阵无缝拼接的一样。
请帮助约翰找到面积最小的模型矩阵,使他能拼出整个大矩阵,当然,模型矩阵的尺寸不一定能整除大矩阵,也就是说你可以用若干个模型矩阵,拼出一个包含大矩阵的更大的矩阵。
Input
第一行, 两个整数R和C
接下来是由大写字母构成的R*C的矩阵
Output
一个整数,表示最小模型矩阵的面积。
Sample Input
2 5ABABABABAB
Sample Output
4
Hint
样例说明:
模型矩阵如下:
AB
BA
拼出的大矩阵如下:
ABABAB
BABABA
Source
usaco 2003 fall Milking Grid
=============================================================================================
分析:
开始拿到这道题的时候我也没什么思路,就想着写暴力骗点分,因为根本没复习,然后看了第3天我还是觉得想
这道比较好写。于是我就去翻了下KMP的讲义,然后发现一个很牛逼的结论:
Fail[]的性质:
1.如果Len%(Len-Fail[len-1])==0则字符串中必存在最小循环节
2.该循环节长度为Len-Fail[len-1]
3.循环次数为Len/(Len-Fail[len-1])
但是这道题是二维的,感觉这个结论还是没啥用= =
然后我就看样例
ABABAB 此时的矩阵为: AB
BABABA BA
他的规模是2*2,然后我就惊奇的发现2是行的最小循环结,也是列的最小循环结(现在看来貌似很明显= =)
然后我就想把它行的循环结*列的循环结不就是答案了么
再来看组数据吧:
我们将每一行看成一个字符
ABAA '#'
ABAA --> '#' -->所以此时的行的循环结长度为1 -->旋转下,再求一次,就得到列的循环结
ABAA '#'
ABAA '#'
-->ABAB-->A -->此时的最小的循环结长度为3 -->最终得到的是1×3的矩阵ABA
B
A
B
==============================================================================================
放代码:
#include<cstdio>#include<cstring>#include<iostream>#include<cstdlib>#define maxn 10005using namespace std;char T[maxn][80],rT[80][maxn];int Fail[maxn];void _get_x(int l) {int j=-1;Fail[0]=-1;for (int i=1;i<l;i++) {while(j>-1&&strcmp(T[j+1],T[i]))j=Fail[j];if(!strcmp(T[j+1],T[i]))j++;Fail[i]=j;}}void _rotate(int x,int y) {for(int i=0;i<y;i++) {for(int j=0;j<x;j++)rT[i][j]=T[j][i];rT[i][x]='\0';}}void _get_y(int l) {int j=-1;Fail[0]=-1;for(int i=1;i<l;i++) {while(j>-1&&strcmp(rT[j+1],rT[i]))j=Fail[j];if(!strcmp(rT[j+1],rT[i]))j++;Fail[i]=j;}}int main() {//freopen("grid.in","r",stdin);//freopen("grid.out","w",stdout);int x,y; scanf("%d%d",&x,&y);for(int i=0;i<x;i++)scanf("%s",T[i]);_get_x(x);//求行的Fail[]//for(int i=0;i<x;i++)cout<<Fail[i]<<" ";//putchar(10);int ans=x-Fail[x-1]-1;//行的最小循环结_rotate(ans,y);//旋转矩阵_get_y(y);//求列的Fail[]//for(int i=0;i<y;i++)cout<<Fail[i]<<" "; //putchar(10);ans=ans*(y-Fail[y-1]-1);//列的循环结printf("%d\n",ans);return 0;}
- 【大渣】【多维KMP】奶牛阵列
- NKOJ 2244 奶牛阵列(KMP+Hash)
- 变成多维阵列
- 该怎麽用 new 来分配多维阵列?
- 【大渣】KMP算法
- BZOJ1827 奶牛大集会
- 【大渣】【KMP】字串清除
- 【奶牛大集会】解题报告
- 树形问题--奶牛大集会
- NKOI 3689 奶牛大聚会
- 阵列
- 【带权中位数】奶牛大集会
- BZOJ1827 [Usaco2010 Mar]gather 奶牛大集会
- 1827: [Usaco2010 Mar]gather 奶牛大集会
- BZOJ1827 [Usaco2010 Mar]gather 奶牛大集会
- 奶牛
- 【多维分析系列】拥抱大数据多维分析查询
- KMP算法大总结
- android studio运行时报错the selected device is incompatible
- HDU-2089-数位DP-不要62
- java手机号归属地验证
- 关于enq: TX - allocate ITL entry的问题分析
- C++ STL算法系列1---count函数
- 【大渣】【多维KMP】奶牛阵列
- Java NIO——Selector机制源码分析---转
- 【Linux学习】epoll详解
- IUnknown
- UVa 12418 - Game of 999
- js常用返回刷新脚本
- spring源码剖析(一)下载spring3.2源代码,并编译源代码
- Android 中webp 的使用
- Qin Shi Huang's National Road System