Life Forms
poj3294:http://poj.org/problem?id=3294
题意:就是求n个串的中一个最大的子串,这个子串在超过n/2的串中出现。
题解:这是一道好题。首先一种解法就是用后缀数组来搞,首先把n个串拼接起来,然后,每个串后面加上一个特殊的额字符,然后求后缀数组以及h数组,然后一个很经典的做法就是二分长度,找到满足条件的长度,然后输出答案。这一题恶心了我一天。各种错误。1,统计的时候出错2是memset的数组开打了,结果T了,3是答案数组没有清空,结果wa了4特殊清空n==1时候没有考虑。printf(%s)是从起始位置输出字符直到遇到\0为止,合法,
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=;
char str[maxn];
int id[maxn];
int wa[maxn],wb[maxn],wv[maxn],wn[maxn],a[maxn],sa[maxn];
int cmp(int* r,int a,int b,int l){
return r[a]==r[b]&&r[a+l]==r[b+l];
}
//n为字符串长度,m为字符的取值范围,r为字符串。后面的j为每次排序时子串的长度
void DA(int* r,int* sa,int n,int m){
int i,j,p,*x=wa,*y=wb,*t;
///对R中长度为1的子串进行基数排序
for(i=; i<m; i++)wn[i]=;
for(i=; i<n; i++)wn[x[i]=r[i]]++;
for(i=; i<m; i++)wn[i]+=wn[i-];
for(i=n-; i>=; i--)sa[--wn[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++)wn[i]=;
for(i=; i<n; i++)wn[wv[i]]++;
for(i=; i<m; i++)wn[i]+=wn[i-];
for(i=n-; i>=; i--)sa[--wn[wv[i]]]=y[i];
///当p=n的时候,说明所有串都已经排好序了
///在第一次排序以后,rank数组中的最大值小于p,所以让m=p
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++;
}
return;
}
///后缀数组 计算height数组
/**
height数组的值应该是从height[1]开始的,而且height[1]应该是等于0的。
原因是,+因为我们在字符串后面添加了一个0号字符,所以它必然是最小的
一个后缀。而字符串中的其他字符都应该是大于0的(前面有提到,使用倍
增算法前需要确保这点),所以排名第二的字符串和0号字符的公共前缀
(即height[1])应当为0.在调用calheight函数时,要注意height数组的范
围应该是[1..n]。所以调用时应该是calheight(r,sa,n)
而不是calheight(r,sa,n+1)。*/
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++);
return;
}
int t;
char temp[];
bool vis[];
bool getsum(int len,int n){
memset(vis,,sizeof(vis));
int counts=;
for(int i=;i<=n;i++){
if(height[i]<len){
memset(vis,,sizeof(vis));
counts=;
}
else {
if(!vis[id[sa[i-]]]){
vis[id[sa[i-]]]=;counts++;
}
if(!vis[id[sa[i]]]){
vis[id[sa[i]]]=;counts++;
}
if(counts>t/){
return true;
}
}
}
return false;
}
char www[maxn];
void print(int len,int n){
memset(vis,,sizeof(vis));
int counts=,tag=;
for(int i=;i<=n;i++){
if(height[i]<len){
memset(vis,,sizeof(vis));
counts=;
tag=;
}
else {
if(!vis[id[sa[i-]]]){
vis[id[sa[i-]]]=;counts++;
}
if(!vis[id[sa[i]]]){
vis[id[sa[i]]]=;counts++;
}
if(counts>t/&&!tag){
tag=;
for(int j=;j<len;j++){
www[j]=a[sa[i]+j]-+'a';
}
www[len]='\0';//这里由于自己没有加上这一句,结果wa了,因为www之前没有清空
printf("%s\n",www);
}
}
} }
char temp2[];
int main(){
int sg=;
while(~scanf("%d",&t)&&t){
if(sg>)puts("");
sg=;
memset(temp2,,sizeof(temp2));
int sumlen=,tp=,r=;
for(int i=;i<=t;i++){
memset(temp,,sizeof(temp));
scanf("%s",temp);
if(i==)
strcpy(temp2,temp);
int len=strlen(temp);
r=max(r,len);
for(int j=;j<len;j++){
a[sumlen+j]=temp[j]-'a'+;
id[sumlen+j]=i;
}
sumlen+=len;
a[sumlen]=tp++;
id[sumlen++]=i;
}
id[sumlen]=t;
DA(a,sa,sumlen+,);
calheight(a,sa,sumlen);
int ans=,l=;
while(l<=r){
int mid=(l+r)/;
if(getsum(mid,sumlen)){
l=mid+;
ans=mid;
}
else{
r=mid-;
}
}
if(ans==)printf("?\n");
else{
if(t==)printf("%s\n",temp2);
else
print(ans,sumlen);
} }
return ;
}
Life Forms的更多相关文章
- Wizard Framework:一个自己开发的基于Windows Forms的向导开发框架
最近因项目需要,我自己设计开发了一个基于Windows Forms的向导开发框架,目前我已经将其开源,并发布了一个NuGet安装包.比较囧的一件事是,当我发布了NuGet安装包以后,发现原来已经有一个 ...
- xamarin.forms新建项目android编译错误
vs2015 update3 新建的xamarin.forms项目中的android项目编译错误.提示缺少android_m2repository_r22.zip,96659D653BDE0FAEDB ...
- ASP.NET Forms 身份验证
ASP.NET Forms 身份验证 在开发过程中,我们需要做的事情包括: 1. 在 web.config 中设置 Forms 身份验证相关参数.2. 创建登录页. 登录页中的操作包括: 1. 验证用 ...
- Xamarin.Forms 简介
An Introduction to Xamarin.Forms 来源:http://developer.xamarin.com/guides/cross-platform/xamarin-forms ...
- C# 定时器 Timers.Timer Forms.Timer
1.定义在System.Windows.Forms里 Windows.Forms里面的定时器比较简单,只要把工具箱中的Timer控件拖到窗体上,然后设置一下事件和间隔时间等属性就可以了 //启动定时器 ...
- Xamarin.Forms 免费电子书
Xamarin Evolve 正在举行,现在已经放出2本免费的Xamarin.Forms 免费电子书,据现场的同学说这两天还有Xamarin.Forms 重磅消息发布: Creating Mobile ...
- 老司机学新平台 - Xamarin Forms开发框架之MvvmCross插件精选
在前两篇老司机学Xamarin系列中,简单介绍了Xamarin开发环境的搭建以及Prism和MvvmCross这两个开发框架.不同的框架,往往不仅仅使用不同的架构风格,同时社区活跃度不同,各种功能模块 ...
- 老司机学新平台 - Xamarin Forms开发框架二探 (Prism vs MvvmCross)
在上一篇Xamarin开发环境及开发框架初探中,曾简单提到MvvmCross这个Xamarin下的开发框架.最近又评估了一些别的,发现老牌Mvvm框架Prism现在也支持Xamarin Forms了, ...
- Nancy之Forms authentication的简单使用
一.前言 想必大家或多或少都听过微软推出的ASP.NET Identity技术,可以简单的认为就是一种授权的实现 很巧的是,Nancy中也有与之相类似的技术Authentication,这两者之间都用 ...
- ASP.NET MVC4 Forms 登录验证
Web.config配置: 在<system.web>节下: <authentication mode="Forms"> <forms loginUr ...
随机推荐
- MySQL源码:索引相关的数据结构
http://www.orczhou.com/index.php/2012/11/mysql-source-code-data-structure-about-index/ 本文将尝试介绍MySQL索 ...
- 追踪CPU跑满 堆栈调试
http://blog.donghao.org/2014/04/24/%E8%BF%BD%E8%B8%AAcpu%E8%B7%91%E6%BB%A1/
- apache kafka技术分享系列(目录索引)--转载
原文地址:http://blog.csdn.net/lizhitao/article/details/39499283 kafka开发与管理: 1)apache kafka消息服务 2)kafak安装 ...
- CentOS Linux修改系统时区
ln –sf /usr/share/zoneinfo/Hongkong /etc/localtime
- jquery判断div是否显示或者隐藏
jquery判断div是否显示或者隐藏 很多时候会要判断一个div是不是显示着,没显示要怎么处理,显示的如何处理: 方法很简单,选择到你要判断的div,再用is(':hidden')判断是否隐藏:或者 ...
- mysql连接错误:Cannot get hostname for your address
问题 环境:win7 + 64Bit + 本地mysql5.6 问题:navicat连接本地mysql数据库,提示“Cannot get hostname for your address”,但是连接 ...
- IIS 上发布ASP.NET5
原文 http://docs.asp.net/en/latest/publishing/iis.html 1.安装HTTP Platform Handler ,这个是必需的,不然无法通过IIS访问AS ...
- Java String.format 自动补全不够的位数
http://www.blogjava.net/java-blog/articles/189040.html
- SQL Server 中WITH (NOLOCK)
with(nolock)的功能: 1: 指定允许脏读.不发布共享锁来阻止其他事务修改当前事务读取的数据,其他事务设置的排他锁不会阻碍当前事务读取锁定数据.允许脏读可能产生较多的并发操作,但其代价是读取 ...
- EF收集
http://www.cnblogs.com/end/archive/2011/08/18/2144250.html http://www.cnblogs.com/zzdfc/archive/2009 ...