zoukankan      html  css  js  c++  java
  • Life Forms POJ

    Life Forms

     POJ - 3294

    题意:给出n个字符串,问出现次数大于n/2的最长的子串(如有多个则都要)

    用特殊字符连接字符串,后缀数组搞一下.

    然后二分长度mid,然后统计次数的时候判断来自哪个字符串,不要重复统计,满足条件就加到答案里去。

    高级数据结构p385有更优的,,有空再看

      1 /*************************************************************************
      2     > File Name: sa.cpp
      3     > Author: yijiull 
      4     > Mail: 1147161372@qq.com 
      5     > Created Time: 2017年09月14日 星期四 23时03分53秒
      6  ************************************************************************/
      7 //#include<bits/stdc++.h>
      8 #include<iostream>
      9 #include<cstdio>
     10 #include<cstring>
     11 using namespace std;
     12 const int maxn=100105;
     13 int len[maxn], sa[maxn], t1[maxn], t2[maxn], c[maxn];
     14 int s[maxn];
     15 char str[maxn];
     16 int h[maxn],rk[maxn];
     17 void build_sa(int n,int m){
     18     int i, *x=t1, *y=t2;
     19     for(i = 0; i < m; i++) c[i]=0;
     20     for(i = 0; i < n; i++) c[x[i]=s[i]]++;
     21     for(i = 1; i < m; i++) c[i]+=c[i-1];
     22     for(i = n-1; i >= 0; i--) sa[--c[x[i]]]=i;
     23     for(int k = 1; k <= n; k <<= 1){
     24         int p=0;
     25         for(i = n-k; i < n; i++) y[p++]=i;
     26         for(i = 0; i < n; i++) if(sa[i]>=k) y[p++]=sa[i]-k;
     27         for(i = 0; i < m; i++) c[i]=0;
     28         for(i = 0; i < n; i++) c[x[y[i]]]++;
     29         for(i = 1; i < m; i++) c[i]+=c[i-1];
     30         for(i = n-1; i >= 0; i--) sa[--c[x[y[i]]]]=y[i];
     31         swap(x,y);
     32         p=1;
     33         x[sa[0]]=0;
     34         for(i = 1; i < n; i++) 
     35             x[sa[i]] = y[sa[i]]==y[sa[i-1]] &&y[sa[i]+k]==y[sa[i-1]+k] ? p-1 : p++;
     36         if(p>=n) break;
     37         m=p;
     38     }
     39 }
     40 void geth(int n){
     41     for(int i = 0; i <= n; i++) rk[sa[i]]=i;
     42     int k=0;
     43     for(int i = 0; i < n; i++){
     44         if(k) k--;
     45         int j = sa[rk[i]-1];
     46         while(s[i+k]==s[j+k]) k++;
     47         h[rk[i]]=k;
     48     }
     49 }
     50 int ans[maxn],vis[110];
     51 int ck(int m,int n,int k){
     52     memset(vis,0,sizeof(vis));
     53     int cnt=0,sz=0;
     54     for(int i = 1; i <= n; i++){
     55         if(h[i]>=m){
     56             for(int j = 1; j <= k; j++) {
     57                 if(sa[i]>len[j-1]&&sa[i]<len[j]) cnt += (!vis[j]) , vis[j]=1;
     58                 if(sa[i-1]>len[j-1]&&sa[i-1]<len[j]) cnt += (!vis[j]) , vis[j]=1;
     59             }
     60         }else{
     61             if(cnt>k/2) ans[++sz]=sa[i-1];
     62             cnt=0;
     63             memset(vis,0,sizeof(vis));
     64         }
     65     }
     66     if(cnt>k/2) ans[++sz]=sa[n];
     67     if(sz){
     68         ans[0]=sz;
     69         return 1;
     70     }
     71     return 0;
     72 }
     73 int main(){
     74     int n;
     75     int kase=0;
     76     len[0]=-1;
     77     while(scanf("%d",&n)!=EOF&&n){
     78         int a=0;
     79         ans[0]=0;
     80         for(int i = 0; i < n; i++){
     81             scanf("%s",str+a);
     82             for(;str[a]!='';a++) s[a]=str[a];
     83             s[a]=300+i;
     84             len[i+1]=a;
     85             a++;
     86         }
     87         s[a-1]=0;
     88         if(kase++) puts("");
     89         build_sa(a,500);
     90         geth(a-1);
     91         int l=1,r=a;
     92         while(l<=r){
     93             int m=(l+r)>>1;
     94             if(ck(m,a,n)) l=m+1;
     95             else r=m-1;
     96         }
     97         if(l==1) puts("?");
     98         else{
     99             for(int i = 1; i <= ans[0]; i++){
    100                 for(int j = ans[i]; j < ans[i]+l-1; j++){
    101                     printf("%c",s[j]);
    102                 }
    103                 puts("");
    104             }
    105         }
    106     }
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    链队列的实现
    LeetCode——Count Complete Tree Nodes
    LeetCode——Lowest Common Ancestor of a Binary Search Tree
    LeetCode——Palindrome Linked List
    中文乱码问题及其解决办法
    LeetCode——Valid Anagram
    TCP/IP网络知识点总结
    深入理解javascript原型和闭包——从【自由变量】到【作用域链】
    AJAX笔试面试题汇总
    前端开发面试知识点大纲
  • 原文地址:https://www.cnblogs.com/yijiull/p/7526556.html
Copyright © 2011-2022 走看看