poj 2185 Milking Grid
2014-02-28 21:22
274 查看
给你一个字符矩阵,然后在这个矩阵中找子矩阵,要求这个子矩阵的字符数最少,且能用这个子字符串拼成包含该字符矩阵(或者就是该字符矩阵)的字符矩阵。
开始我理解的时候,觉得可以换这个子矩阵的方向,结果看着别人都是直接用原始方向,不知道是我读题不仔细还是这题的信息有缺省,反正这题如果子字符串能转动,
那么这题肯定很麻烦,但是如果不变方向,直接求每行的循环子串的字符数,然后求lcm所有行的循环子串的字符串。列也按照同样的方法进行处理,然后2个相乘就解决了。这里需要注意一点,如果这个lcm超过了行或者列的总长度,直接取长度就行。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int Maxr = 10010, Maxl = 80;
char str[Maxr][Maxl];
int r, l, next[Maxr], lent;
int get_next_r(int x) {
int i = 0, j = -1;
next[0] = j;
while(i < l) {
if(j == -1||str[x][j] == str[x][i])
{
i++, j++;
next[i] = j;
}
else
j = next[j];
}
return i - next[i];
}
int get_next_c(int x) {
int i = 0, j = -1;
next[0] = j;
while(i < r) {
if(j == -1||str[j][x] == str[i][x])
{
i++, j++;
next[i] = j;
}
else
j = next[j];
}
return i - next[i];
}
int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}
int lcm(int a,int b) {
return a/gcd(a, b)*b;
}
int main(void)
{
while(scanf("%d%d",&r,&l)!=EOF) {
for(int i = 0; i < r; ++i)
{
scanf("%s",str[i]);
}
int lr = 1, ll = 1;
for(int i = 0; i < r; ++i) {
lr = lcm(lr,get_next_r(i));
}
if(lr > l)
lr = l;
for(int i = 0; i < l; ++i) {
ll = lcm(ll,get_next_c(i));
}
if(ll > r)
ll = r;
cout<<ll*lr<<endl;
}
return 0;
}
开始我理解的时候,觉得可以换这个子矩阵的方向,结果看着别人都是直接用原始方向,不知道是我读题不仔细还是这题的信息有缺省,反正这题如果子字符串能转动,
那么这题肯定很麻烦,但是如果不变方向,直接求每行的循环子串的字符数,然后求lcm所有行的循环子串的字符串。列也按照同样的方法进行处理,然后2个相乘就解决了。这里需要注意一点,如果这个lcm超过了行或者列的总长度,直接取长度就行。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int Maxr = 10010, Maxl = 80;
char str[Maxr][Maxl];
int r, l, next[Maxr], lent;
int get_next_r(int x) {
int i = 0, j = -1;
next[0] = j;
while(i < l) {
if(j == -1||str[x][j] == str[x][i])
{
i++, j++;
next[i] = j;
}
else
j = next[j];
}
return i - next[i];
}
int get_next_c(int x) {
int i = 0, j = -1;
next[0] = j;
while(i < r) {
if(j == -1||str[j][x] == str[i][x])
{
i++, j++;
next[i] = j;
}
else
j = next[j];
}
return i - next[i];
}
int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}
int lcm(int a,int b) {
return a/gcd(a, b)*b;
}
int main(void)
{
while(scanf("%d%d",&r,&l)!=EOF) {
for(int i = 0; i < r; ++i)
{
scanf("%s",str[i]);
}
int lr = 1, ll = 1;
for(int i = 0; i < r; ++i) {
lr = lcm(lr,get_next_r(i));
}
if(lr > l)
lr = l;
for(int i = 0; i < l; ++i) {
ll = lcm(ll,get_next_c(i));
}
if(ll > r)
ll = r;
cout<<ll*lr<<endl;
}
return 0;
}
相关文章推荐
- Windows 7 开机自动拨号 常用的五种方
- JAVA JDK安装
- [Splay伸展树]splay树入门级教程
- Poj 1041 John's trip (Fleury算法求欧拉回路路径)
- cmd命令中截取日期字符
- 训练局限玻尔斯曼机(Training Restricted Boltzmann Machines)----第一讲 介绍
- Servlet(一)——刨根问底
- JDK动态代理学习笔记
- php redis 接口说明
- SQL<一>--游标使用
- 内存分析。
- hadoop怎样创建 mapreduce项目简易例子教程
- DevOps是一门哲学
- 九度OJ 1038 Sum of Factorials
- UBOOT移植OK210开发板
- POJ 2761 Feed the dogs
- mysql列属性auto(mysql笔记四)
- 创客文章
- POJ_3044_City Skyline(栈)
- 在AWS上安装laravel框架