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 ...
随机推荐
- Gstreamer 数据流线程(GstTask / GstTaskPool)分析
作者:fengcc 原创文章 转载请注明出处 GStreamer 是一个基于流水线的多媒体框架,基于 GObject,以 C 语言写成. 凭借 GStreamer,程序员可以很容易地创建各种多媒体功能 ...
- 基于 CoreText 实现的高性能 UITableView
引起UITableView卡顿比较常见的原因有cell的层级过多.cell中有触发离屏渲染的代码(譬如:cornerRadius.maskToBounds 同时使用).像素是否对齐.是否使用UITab ...
- Chapter 5. The Gradle Wrapper 关于gradle wrapper
Most tools require installation on your computer before you can use them. If the installation is eas ...
- xml--小结②XML的基本语法
二.XML的基本语法1.文档声明:作用:用于标识该文档是一个XML文档.注意事项:声明必须出现在文档的第一行(之前连空行都不能有,也不能有任何的注释) 最简单的XML声明:<?xml versi ...
- JS获取页面上所有input
for (var i = 0; i < document.getElementsByTagName("input").length; i++) { if (document. ...
- Oracle 检验身份证是否正确的存储过程
) ) ); ); ); ); ); ); ); ; , , , , , , , , , , , , , , , , , ); ; , ) ); .. loop )) ) ); , )), ), ...
- swift 遍历
最简单的一个遍历数组 for 随便起个名字 in 升级 上面的看不懂的话,这个应该会简单点 import UIKit let interestingNumbers = [ ,,,,,], ,,,,,] ...
- How To Read a Paper.md
@ Titile How To Read a Paper.md @ author Keshav, 译 uuplusu # 1. Intro 1. 读论文重要 2. 没有人教 3. ...
- 《wc》-linux命令五分钟系列之十七
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- Activity启动模式图文详解
转载自:http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0520/2897.html 英文原文:Understand Android A ...