poj 3294 后缀数组

高频面试题-项目介绍篇 聊聊如何介绍项目经历。 阅读详情

链接 http://poj.org/problem?id=3294

题意:给你n个字符串,n小于100,每个字符串的长度小于1000,让你找出至少在一半的字符串中出现过得最长的一个字串,如果有多个,那就按照字典序逐个输出

思路:我们先把所有的字符串连成一个大的字符串,每个字符串之间用一个没有出现过得字符xx隔开(注意这个字符也要两两不同),在把所有串连成一个大串的过程中,我们用一个set来把每个xx的位置都存下来。接着我们跑一边后缀数组,然后二分枚举目标串的最大长度y,看有没有一个长度为y的字串在至少一半的字符串中出现过,方法是从前到后遍历一边height数组,肯height的值是不是大于y,如果是,就表示这相邻的两个后缀的公共前缀的长度大于y,这时候我们需要判断一下这些串是不是在原来的一个字符串中,如果是,那么就不能算,我们可以知道这两个串的位置i和j,我们只要用set的upper_bone函数求出在i和j后面的第一个字符xx,看是否相等,就知道他们是不是在一个串中了,然后我们用一个flag数组把出现过得字串记录下来,再接着往后扫描height数组,如果还是>y,那么就再求出他们这两个后缀属于的原先的字符串的下标,看之前有没有出现过,没有就num++;如果<y,就看2*num是否大于n,至于怎么输出,我们只要从前往后扫描height数组,操作和之前的判断一样,找到了就输出,因为一定是按字典序拍好的。

是个好题,多思考,一些细节就自己独立完成吧

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<string>
#include<map>
using namespace std;

int const N= 200010;
int wa[N], wb[N], w[N], wv[N];
int sa[N], height[N], Rank[N],r[N];
int dp[N][25];
char str1[N],str2[N];
int n;
int len;
set<int>g;
map<int,int>gg;

int cmp( int* r, int a, int b, int L ){
    return r[a]== r[b] && r[a+ L]== r[b+ L];
}

void da( int* r, int* sa, int n, int m ){
    int i, j, p, *x= wa, *y= wb, *t;
    for( i= 0; i< m; ++i ) w[i]= 0;
    for( i= 0; i< n; ++i ) w[ x[i]= r[i] ]++;
    for( i= 1; i< m; ++i ) w[i]+= w[i-1];
    for( i= n- 1; i>= 0; i-- ) sa[ --w[ x[i] ] ]= i;

    for( j= 1, p= 1; p< n; j*= 2, m= p ){
        for( p= 0, i= n- j; i< n; ++i ) y[p++]= i;
        for( i= 0; i< n; ++i )
            if( sa[i]>= j ) y[p++]= sa[i]- j;

        for( i= 0; i< n; ++i ) wv[i]= x[y[i]];
        for( i= 0; i< m; ++i ) w[i]= 0;
        for( i= 0; i< n; ++i ) w[ wv[i] ]++;
        for( i= 1; i< m; ++i ) w[i]+= w[i-1];
        for( i= n- 1; i>= 0; i-- ) sa[ --w[ wv[i] ] ]= y[i];

        t= x, x= y, y= t, p= 1; x[ sa[0] ]= 0;
        for( i= 1; i< n; ++i )
            x[ sa[i] ]= cmp( y, sa[i-1], sa[i], j )? p- 1: p++;
    }
}

void callheight( int* r, int*sa, int n ){
    int i, j, k= 0;
    for( i= 1; i<= n; ++i ) Rank[ sa[i] ]= i;
    for( i= 0; i< n; height[ Rank[i++] ]= k )
        for( k?k--:0, j= sa[ Rank[i]- 1]; r[i+k]== r[j+k]; k++ );
}

void RMQ(int n){
    int m=(int)(log(n*1.0)/log(2.0))+2;
    for(int i=1;i<=n;i++)
        dp[i][0]=height[i];
    for(int i=1;i<m;i++){
        for(int j=1;j<=n;j++) if(j+(1<<i)-1<=n){
            dp[j][i]=min(dp[j][i-1],dp[j+(1<<(i-1))][i-1]);
        }
    }
}

int getRMQ(int l,int r){
    if(l>r) swap(l,r);
    l++;
    int m=(int)(log(1.0*r-l+1)/log(2.0));
    return min(dp[l][m],dp[r-(1<<m)+1][m]);
}

//以上都是模板

bool check(int x){
    bool flag[110];
    int num=0;
    memset(flag,0,sizeof(flag));
    for(int i=1;i<=len;i++){
        if(height[i]>=x){
            int a=*g.upper_bound(sa[i-1]);
            int b=*g.upper_bound(sa[i]);
            if(flag[gg[a]]==0){
                num++;
                flag[gg[a]]=1;
            }
            if(flag[gg[b]]==0){
                num++;
                flag[gg[b]]=1;
            }
        }
        else {
            if(2*num>n) return 1;
            num=0;
            memset(flag,0,sizeof(flag));
        }
    }
    if(2*num>n) return 1;
    return 0;
}

void print(int x){
    bool flag[110];
    memset(flag,0,sizeof(flag));
    int num=0;
    for(int i=1;i<=len;i++){
        if(height[i]>=x){
            int a=*g.upper_bound(sa[i-1]);
            int b=*g.upper_bound(sa[i]);
            if(flag[gg[a]]==0){
                num++;
                flag[gg[a]]=1;
            }
            if(flag[gg[b]]==0){
                num++;
                flag[gg[b]]=1;
            }
        }
        else {
            if(2*num>n){
                int xx=sa[i-1];
                for(int i=0;i<x;i++)
                    printf("%c",str1[xx+i]);
                cout<<endl;
            }
            num=0;
            memset(flag,0,sizeof(flag));
        }
    }
    if(2*num>n){
        int xx=sa[len-1];
        for(int i=0;i<x;i++)
            printf("%c",str1[xx+i]);
        cout<<endl;
    }
    cout<<endl;
}

int main()
{
    while(cin>>n&&n){
        if(n==1){
            cin>>str1;
            cout<<str1<<endl<<endl;
            continue;
        }
        getchar();
        len=0;
        g.clear();
        gg.clear();
        memset(str1,0,sizeof(str1));
        char xx=1;
        int yy=0;
        for(int i=0;i<n;i++){
            cin>>str2;
            int len2=strlen(str2);
            strcat(str1,str2);
            len+=len2;
            str1[len++]=xx;
            xx=(xx+1)%50;
            if(xx==0) xx++;
            str1[len]=0;
            g.insert(len-1);
            gg[len-1]=yy++;
        }
        for(int i=0;i<len;i++)
            r[i]=str1[i];
        r[len]=0;
        da(r,sa,len+1,256);
        callheight(r,sa,len);
        int l=0,r=len,mid;
        while(r-l>1){
            mid=(l+r)/2;
            if(check(mid)) l=mid;
            else r=mid-1;
        }
        if(check(l+1)) l++;
        if(l==0) cout<<'?'<<endl<<endl;
        else print(l);
    }
    return 0;
}


R语言绘图进阶:五大工具高效组合多图(cowplot、patchwork、layout、par、gridExtra) 本文详细介绍了R语言中五大高效组合多图的工具:cowplot、patchwork、layout、par和gridExtra。针对不同场景提供了实用指南,帮助数据分析师解决图表排版难题,提升报告专业度。特别推荐cowplot用于ggplot2图形组合,patchwork提供最简洁语法,layout则支持完全自定义布局。 阅读详情

相关推荐

BES平台集成第三方音频算法避坑指南:以声加ENC为例,聊聊文件放置、内存分配与授权那些事

本文详细解析了在BES平台上集成声加ENC降噪算法的全流程,包括技术选型、系统架构设计、内存管理及量产授权等关键环节。特别针对BES平台的双核架构和内存限制,提供了文件放置、内存分配与授权验证的实用解决方案,帮助开发者高效实现音频算法集成。

weixin_33720956的博客 514

POJ 3294 后缀数组+单调栈 || POJ 2758 后缀数组

DC3 #pragma comment(linker, "/STACK:102400000,102400000") //#include<bits/stdc++.h> #include<cstdio> #include<cstring> #include<string> #include<vector> #include<stack...

打过ICPC/CCPC,学习ACM算法,Linux内核,Openharmony,加油努力开心珍惜 670

告别“静态组件”:Adobe XD的堆栈+状态,打造“活”的响应式UI

今天,我想分享一套能彻底告别这种“笨方法”的、Adobe XD中的进阶技巧,通过组合使用“堆栈”、“内边距”和“组件状态”,去构建一个能自动适应内容、真正“活”起来的智能响应式组件。

Kingsdesigner的博客 760

POJ3294:Life Forms——后缀数组

题面   POJ3294 解析    翻译一下题意:给定n个字符串,求最长的字符串 S 的长度,使得 S 至少为其中 n/2+1 个字符串的子串, 并输出所有的S,若不存在,则输出'?'。(n<=100)   此题与POJ3261类似(我的博客),都是相同套路,后缀数组+二分答案   当然是把每个字符串连在一起,组成一个大的字符串,再在上面建立后缀数组。但是这里有个细节...

weixin_30532973的博客 172

智能驾驶小白必看:MEB低速紧急制动系统的工作原理与传感器配置详解

本文深入解析了MEB低速紧急制动系统的工作原理与传感器配置。该系统作为智能驾驶的关键安全冗余,专为应对停车场、拥堵路段等复杂低速场景设计。文章详细拆解了其如何通过超声波雷达、环视摄像头等传感器融合感知环境,并基于碰撞时间(TTC)等模型进行风险评估与分级制动,最终实现主动防碰撞,是智能驾驶技术实用化的重要体现。

c2d3e4f的博客 1131

HFSS学习笔记——Vivaldi天线仿真(一)

Vivaldi 天线HFSS仿真,HFSS中指数曲线绘制及曲面绘制。

and_future的博客 1万+

POJ - 3294 Life Forms

传送门:POJ - 3294 (类似题目POJ - 3450) 题意:给你n个字符串,求在不小于k/2个字符串中出现过的最长子串。 题解:首先将n个字符串连起来,中间用不一样且没出现过的字符连起来(这个地方让我wa了好几发!!),然后二分字串的长度,将后缀分成若干组,判断每组的后缀是否在不小于k个的原串中出现过,数组sum记录每个最长字符串在原串中出现的位置sa[i]。 1 #...

只能过样例嘤嘤嘤的博客 253

Android P车机添加屏幕多指全局自定义手势操作

参照原生状态栏全局下拉手势拦截,实现屏幕全局多指手势响应操作,并对手势进行转换为KeyEvent,以便项目自定义手势行为或应用拦截手势行为。

shusuanly的博客 1251

poj 3294(后缀数组)

题意:给出n个字符串,求出现次数超过n/2次及以上的最长子串,如果有多组按字典序输出,没有输出?。 题解:多个字符串的处理方式是把所有串连接起来,用没有出现在串中且字典序最大的字符分割,然后二分出一个长度x去判断是否有长度不小于x的公共前缀出现了n/2次以上。需要注意为了判断两个公共前缀不在一个串中,要把每个串的起始位置记录到sum数组,然后连续的height[i]>=x情况下,如果sa[i]所在

俯瞰风景 726

基于工作流的低代码AI应用开发:Flock平台核心架构与实战指南

在AI应用开发领域,工作流编排正成为连接大语言模型(LLM)能力与复杂业务逻辑的关键技术。其核心原理是将任务分解为模块化节点,通过可视化方式定义执行顺序与数据流向,从而实现灵活可控的自动化流程。这种范式极大地提升了开发效率,降低了技术门槛,使得开发者能够聚焦于业务设计而非底层代码。在技术价值层面,工作流编排支持检索增强生成(RAG)、多智能体协作等高级模式,并能通过人工干预节点确保关键流程的可靠性与合规性。其典型应用场景包括智能客服、自动化办公、数据分析助手等。本文以Flock平台为例,深入解析了如何利用其

weixin_26848497的博客 381

【WRF-Chem教程第四期上】运行 WRF-Chem 模型

完整介绍运行 WRF-Chem 模型的详细步骤

WW、forever的博客 3111

poj3294Life Forms(后缀数组)

题意:输入n个DNA序列,你的任务是求出一个长度最大的字符串,使得它在超过一半的DNA序列中连续出现。如果有多解,按照字典序从小到大输出所有解。 【输入格式】 输入包含多组数据。每组数据第一行为DNA串的个数n(1<=n<=100),以下n行每行为一个由不超过1000个小写字母组成的非空字符串。输入结束标志为n=0。 【输出格式】 对于每组数据,输出所有解,按照字典序从小到大排列。如果无解,

Hawkeye_z的博客 562

Android-Zygote进程的诞生—从init到Zygote启动

Android Zygote进程启动流程解析 Android系统的Zygote进程是所有应用进程的父进程,由init进程创建。启动流程分为: 内核阶段:加载init进程(PID=1) init进程阶段: 挂载基础文件系统(tmpfs、proc等) 设置SELinux安全策略 解析init.rc配置文件 Zygote启动:init进程通过app_process启动Zygote,预加载系统资源 SystemServer:Zygote fork出系统服务进程 关键点: init是用户空间第一个进程......

保持专注,保持热爱 637

poj3294 后缀数组+二分

(http://www.elijahqi.win/2017/07/19/poj3294-%E5%90%8E%E7%BC%80%E6%95%B0%E7%BB%84%E4%BA%8C%E5%88%86/) Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 15713 Accepted: 4615 De...

Elijahqi 368

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

【poj3294-不小于k个字符串中最长公共子串】后缀数组

【poj3294-不小于k个字符串中最长公共子串】后缀数组 1.注意每两个串之间的连接符要不一样。 2.分组的时候要注意最后一组啊!又漏了! 3.开数组要考虑连接符的数量。100010是不够的至少要101000。 1 #include&lt;cstdio&gt; 2 #include&lt;cstdlib&gt; ...

qq_25768269的博客 289

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

poj 3294 Life Forms (后缀数组)

poj 3294 Life Forms 题意:给出n个字符串,问这n个字符串中,一半以上字符串拥有的最长连续公共子串有多少,按字典序全部输出来。 解题思路:一般这种最长连续公共子串什么的都是后缀数组,二分答案。。先将n个字符连起来,预处理一遍,sa,rank,height都算出来(这些我都放在模板里),然后就是二分答案了。在判断某个长度是否符合要求时,根据height值,将按height值排序

No__stop 1058

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

POJ - 3294 - Life Forms(后缀数组,二分+分组技巧)

POJ - 3294 - Life Forms(后缀数组,二分+分组技巧) 题目链接:传送门 思路: part1 对于n个字符串,我们只需要找至少在n/2+1个字符串出现过的最长子串即可。 part2 如果k=1,我们只需输出最长的字符串即可(这里n肯定等于1,即本身) 否则我们首先将这n个字符串用不相同的特殊字符连接成一个字符串S,并记录每个下标位置属于哪个字符串。 二分...

Dch19990825的博客 325

POJ3294-Life Forms(后缀数组)

POJ3294-Life Forms(后缀数组)You may have wondered why most extraterrestrial life forms resemble humans, differing by superficial traits such as height, colour, wrinkles, ears, eyebrows and the like. A few

Static_Ricardo的博客 375

POJ 3294 后缀数组

题目链接:http://poj.org/problem?id=3294 题意:给定n个字符串,求一个最长子串要求在超过一半的字符串中出现过。 如果多解按字典序输出 思路:根据<<后缀数组——处理字符串的有力工具>>的思路,将 n个字符串连起来, 中间用不相同的且没有出现在字符串中的字符隔开, 求后缀数组。然后二分答案,把题目变成判定性问题:判断是否存在两个长度为k...

weixin_33923148的博客 91

【POJ】3294 Life Forms 【后缀数组——求在超过一半串中出现的最长串】

传送门:【POJ】3294 Life Forms 题目分析:我们将所有的串合并成一个串,相邻两串中间用分隔符隔开,注意分隔符一定要用各不相同的且都不在原串中出现的。然后构造后缀数组,这个用倍增算法就好了。然后,我们二分最长串的长度k,然后扫一遍height数组,当>=k时我们统计出现在不同串的个数cnt,当n/2,是的话返回yes,否则返回no,yes的话就调整下界,否则调整上界。然后输

poursoul 803

poj3294 Life Forms - 后缀数组

题目链接:http://poj.org/problem?id=3294 题目大意:求出现在超过一半字符串中的最长子串 解题思路:后缀数组+二分 二分枚举最长子串的长度,根据height[]分组,验证是否存在 在一组中出现了超过一半次数的字符串。 (这是height[]的应用之一,罗穗骞大大的论文里就有讲~) #include<cstdio> #i...

154

【后缀数组】【poj 3294】Life Forms

http://poj.org/problem?id=3294 hehe被虐 基本应用——不小于k个字符串的最长子串 //#define _TEST _TEST #include #include #include #include #include #include using namespace std; /***************************

willinglive 566

poj3294 后缀数组emmm

TLE一下午,memset不能用太多,吧memset的数组大小设置成正好,别设置太大 #include<cstdio> #include<algorithm> #include<iostream> #include<cmath> #include<cstdlib> #include<cstring> #include...

甦萌的博客 177

POJ 3294 Life Forms(后缀数组+二分答案)

【题目链接】http://poj.org/problem?id=3294 【题目大意】   求出在至少在一半字符串中出现的最长子串。   如果有多个符合的答案,请按照字典序输出。 【题解】   将所有的字符串通过不同的拼接符相连,作一次后缀数组,   二分答案的长度,然后在h数组中分组,判断是否可行,   按照sa扫描输出长度为L的答案即可。注意在一个...

weixin_30731305的博客 152

Poj 3294 Life Forms (后缀数组 + 二分 + Hash)

题目链接:   Poj 3294 Life Forms 题目描述:   有n个文本串,问在一半以上的文本串出现过的最长连续子串? 解题思路:   可以把文本串用没有出现过的不同字符连起来,然后求新文本串的height。然后二分答案串的长度K,根据K把新文本串的后缀串分块,统计每块中的原文本串出现的次数,大于原文本串数目的一半就作为答案记录下来,对于输出字典序,height就是排好序的后缀...

weixin_30645617的博客 122

【POJ3294】 后缀数组+二分

POJ3294 链接 题意为给你n个字符串,求至少出现在[n2][n2][ \frac{n}{2}]个串中的最长公共子串,如果有多个全部输出。 本题和上题几乎一模一样,只是要把判断条件由来自n个串改成来自[n2][n2][\frac{n}{2}]个串,注意一下存储答案的方式,如果当前二分量存在答案并且第一次访问,那么清空vectorvectorvector,如果不是第一次访问,就在vecto...

lajiyuan的博客 507
上一篇: poj 1679 The Unique MST 最小生成树
下一篇: poj 3237 树链剖分
ACMer_浩
博客等级 码龄12年 0粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值