TZOJ3043: 取个标题好难 最长的出现次数>=k的不重复子串长度
3043: 取个标题好难 
Total Submit: 17 Accepted:4
Description
你是否经常在写完文章之后为文章取一个合适的标题而苦恼?这里提供一个很有趣的方法。
首先,标题应该概括文章的内容。为了简单起见,如果一个短语在文章中不重叠地出现了至少k次,那么这个短语就可以作为标题。例如,”dadadad”中,短语”dad” 不重叠地出现了两次,而不是三次。
其次,标题越长越好。长标题才能吸引眼球。
最后,这件事应该让计算机来做比较省事。
所以,请编写一个程序,根据给定的k和一段文章,给这篇文章取个标题。
Input
输入包括多组数据。
每组数据第一行为整数k,第二行为一个字符串表示文章内容,为了简化问题,字符串仅含小写字母。字符串长度不超过10000。
输入数据以k=0结束。
Output
对每组数据输出最长的标题长度,如果找不到符合要求的标题,则输出0。
Sample Input
3
abababa
1
apple
4
abababa
5
abababa
0
Sample Output
2
5
1
0
最长的出现次数>=k的不重复子串长度,这个题目明显可以hash,然后在二分长度,排序的时候将位置也标记下,最后判断下就可以了
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ulint;
#define maxn 23333
const ulint x=;
int M;
char in[maxn];
ulint has[maxn];
int pos[maxn];
int id[maxn];
ulint xp[maxn];
ulint H[maxn];
bool cmp(int a,int b)
{
return has[a]<has[b]||has[a]==has[b]&&a<b;
}
bool check(int mid,int n)
{
pos[mid]=;
id[]=;
for(int i=; i+mid-<n; i++)//就算每一段的hash值
id[i]=i,has[i]=H[i]-H[i+mid]*xp[mid];
sort(id,id+n-mid+,cmp);//按hash值排序
int cnt=;
bool ret=;
int tmp=id[];
for(int i=; i<=n-mid; i++)
if(has[id[i]]==has[id[i-]])
{
if(id[i]-tmp>=mid)
cnt++,tmp=id[i];
if(cnt>=M)
pos[mid]=max(pos[mid],tmp),ret=;
}
else
cnt=,tmp=id[i];
return ret;
}
int main()
{
xp[]=;
for(int i=; i<maxn; i++)//预处理x次幂项
xp[i]=xp[i-]*x;
while(scanf("%d",&M),M)
{
scanf("%s",in);
int n=strlen(in);
if(M==)
{
printf("%d\n",n);
continue;
}
H[n]=;
for(int i=n-; i >= ; i--)//预处理H[i]=s[i]+s[i+1]*x+...+s[n]*x^(n-i)
H[i]=H[i+]*x+(in[i]-'a');
int L=,R=n,mid,len=;
while(L<=R)
{
mid=(L+R)>>;
if(check(mid,n))
{
len=mid;
L=mid+;
}
else
R=mid-;
}
if(len==)
printf("0\n");
else
printf("%d\n",len);
}
return ;
}
然后也可以后缀数组,我们之前那个题允许重复,直接判断height即可,这个题目要保存sa[i],然后排序判断是否重复
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <set>
#define dbg(x) std::cout<<#x<<" = "<< (x)<< "\n"
#define maxn 20005
int wa[maxn],wb[maxn],wv[maxn],ws[maxn],m;
int cmp(int *r,int a,int b,int l)
{
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void getsa(int *r,int *sa,int n,int m)
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=; i<m; i++) ws[i]=;
for(i=; i<n; i++) ws[x[i]=r[i]]++;
for(i=; i<m; i++) ws[i]+=ws[i-];
for(i=n-; i>=; i--) sa[--ws[x[i]]]=i;
for(j=,p=; p<n; j*=,m=p)
{
for(p=,i=n-j; i<n; i++) y[p++]=i;
for(i=; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
for(i=; i<n; i++) wv[i]=x[y[i]];
for(i=; i<m; i++) ws[i]=;
for(i=; i<n; i++) ws[wv[i]]++;
for(i=; i<m; i++) ws[i]+=ws[i-];
for(i=n-; i>=; i--) sa[--ws[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=,x[sa[]]=,i=; i<n; i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
}
int rank[maxn],height[maxn];
void calheight(int *r,int *sa,int n)
{
int i,j,k=;
for(i=; i<=n; i++) rank[sa[i]]=i;
for(i=; i<n; height[rank[i++]]=k)
for(k?k--:,j=sa[rank[i]-]; r[i+k]==r[j+k]; k++);
}
int a[maxn];
int check(int *sa,int n,int k)
{
int i,cnt=;
a[]=sa[];
for(i=; i<=n; i++)
{
if(height[i]>=k)
{
a[cnt++]=sa[i];
}
else
{
if(cnt>=m)
{
std::sort(a,a+cnt);
int x=a[],tot=cnt;
for(int i=; i<tot; i++)
{
if(a[i]-x<k)cnt--;
else x=a[i];
}
if(cnt>=m)return ;
}
cnt=,a[]=sa[i];
}
}
std::sort(a,a+cnt);
int x=a[],tot=cnt;
for(int i=; i<tot; i++)
{
if(a[i]-x<k)cnt--;
else x=a[i];
}
if(cnt>=m)return ;
return ;
}
int r[maxn],sa[maxn];
char str[maxn];
int main()
{
//freopen("test.in","r",stdin);
while(scanf("%d",&m),m)
{
scanf("%s",str);
int n=strlen(str);
if(m==)
{
printf("%d\n",n);
continue;
}
for(int i=; i<n; i++)r[i]=str[i];
r[n]=;
getsa(r,sa,n+,);
calheight(r,sa,n);
int L=,R=n,mi,len=;
while(L<=R)
{
mi=(L+R)>>;
if(check(sa,n,mi))L=mi+,len=mi;
else R=mi-;
}
printf("%d\n",len);
}
return ;
}
TZOJ3043: 取个标题好难 最长的出现次数>=k的不重复子串长度的更多相关文章
- Poj 1743——Musical Theme——————【后缀数组,求最长不重叠重复子串长度】
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 22499 Accepted: 7679 De ...
- 最长不重复子串长度,时间复杂度O(n),空间复杂度O(n),Python实现
def lengthOfLongestSubstring(s): res = 0 d = {} tmp = 0 start = 0 for i in range(len(s)): if s[i] in ...
- LeetCode:Longest Substring Without Repeating Characters(最长不重复子串)
题目链接 Given a string, find the length of the longest substring without repeating characters. For exam ...
- POJ 3261 Milk Patterns 可重复k次的最长重复子串
Milk PatternsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=3261 Description ...
- Longest Substring Without Repeating Characters 最长不重复子串
只遍历一次字符串即可求出最长不重复子串的长度. int lengthOfLongestSubstring(string s) { vector<,-); //记录字符上一次出现的位置,ASCII ...
- poj 1743 男人八题之后缀数组求最长不可重叠最长重复子串
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 14874 Accepted: 5118 De ...
- [Jobdu] 题目1530:最长不重复子串
题目描述: 最长不重复子串就是从一个字符串中找到一个连续子串,该子串中任何两个字符都不能相同,且该子串的长度是最大的. 输入: 输入包含多个测试用例,每组测试用例输入一行由小写英文字符a,b,c... ...
- 【poj1743-Musical Theme】不可重叠最长重复子串-后缀数组
http://poj.org/problem?id=1743 这题是一道后缀数组的经典例题:求不可重叠最长重复子串. 题意: 有N(1 <= N <=20000)个音符的序列来表示一首乐曲 ...
- 九度oj 题目1530:最长不重复子串
题目描述: 最长不重复子串就是从一个字符串中找到一个连续子串,该子串中任何两个字符都不能相同,且该子串的长度是最大的. 输入: 输入包含多个测试用例,每组测试用例输入一行由小写英文字符a,b,c... ...
随机推荐
- EasyHook实用指南
所谓实用指南就是全是干货,没那么多虚头巴脑的东西,真正要用的人会发现对自己有用的东西,浅尝辄止的人看起来会不知所云. FileMon自己实做的过程中遇到的问题: 1. exe和dll文件必须强命名,对 ...
- mac home brew install go
mac利器home brew安装Go 首先你得需要安装home brew和ruby环境(因为home brew依赖ruby) 如果没有请自行到链接安装 准备好之后就开始安装go了 brew updat ...
- 第二天了,由于博主太分心了,看看就跑去研究了一下ssh和ufw以及nmap,现在急需记录一下啦,哈哈!
昨天看到了视频的ssh远程连接,因为我点电脑上装的是一个ubuntu的虚拟机,我根据视频看了一下,自己又试用了一下,我发现自己的ubuntu是能够远程到自己的Mac电脑上,一开始主要是因为自己不能连接 ...
- Java面试不得不知的问题(一)
程序员面试 1. 面向对象的特征有哪些方面 · 抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分, ...
- 5、SpringBoot+Mybatis整合------多对多
开发工具:STS 代码下载链接:https://github.com/theIndoorTrain/SpringBoot_Mybatis/tree/3baea10a3a1104bda815c20695 ...
- Onboard,迷人的引导页样式制作库
简介 Onboard主要用于引导页制作,源码写的相当规范,值得参考. 项目主页: https://github.com/mamaral/Onboard 实例下载: https://github.com ...
- Oracle多表连接方法
笛卡尔连接[结果集为各表记录的乘积] SELECTt * FROM table_1, table_2, table_n SELECTt * FROM table_1 CROSS JOIN table_ ...
- CMD批处理复制目录下所有文件
从我接触编程时,WIN7已经是最普及的系统了. 有一天,我需要在服务器更新某个软件或游戏的时候,我都需要先在其中一台服务器下载更新, 然后同步到其他服务器,而且这种操作也是非常频繁的,我就想写个批处理 ...
- UVA_1434_YAPTCHA
The math department has been having problems lately. Due to immense amount of unsolicited automated ...
- MySQL巧用FIND_IN_SET和GROUP_CONCAT函数减少Java代码量
数据库表简介:物品表 `id` int(11) '物品id,唯一标识', `name` varchar(255) '物品名称', `level` int(11) '物品类别等级,礼品包为最高级1,类 ...