题目链接:http://poj.org/problem?id=3450

题目分类:后缀数组

题意:求n个串的最长公共字串(输出字串)

  1. //#include<bits/stdc++.h>
  2. #include<stdio.h>
  3. #include<math.h>
  4. #include<algorithm>
  5. #include<string.h>
  6.  
  7. using namespace std;
  8.  
  9. #define N 200005
  10.  
  11. int wa[N],wb[N],wsf[N],wv[N],sa[N];
  12. int rank[N],height[N],s[N];
  13. //sa:字典序中排第i位的起始位置在str中第sa[i]
  14. //rank:就是str第i个位置的后缀是在字典序排第几
  15. //height:字典序排i和i-1的后缀的最长公共前缀
  16. int cmp(int *r,int a,int b,int k)
  17. {
  18. return r[a]==r[b]&&r[a+k]==r[b+k];
  19. }
  20. void getsa(int *r,int *sa,int n,int m)//n要包含末尾添加的0
  21. {
  22. int i,j,p,*x=wa,*y=wb,*t;
  23. for(i=; i<m; i++) wsf[i]=;
  24. for(i=; i<n; i++) wsf[x[i]=r[i]]++;
  25. for(i=; i<m; i++) wsf[i]+=wsf[i-];
  26. for(i=n-; i>=; i--) sa[--wsf[x[i]]]=i;
  27. p=;
  28. j=;
  29. for(; p<n; j*=,m=p)
  30. {
  31. for(p=,i=n-j; i<n; i++) y[p++]=i;
  32. for(i=; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
  33. for(i=; i<n; i++) wv[i]=x[y[i]];
  34. for(i=; i<m; i++) wsf[i]=;
  35. for(i=; i<n; i++) wsf[wv[i]]++;
  36. for(i=; i<m; i++) wsf[i]+=wsf[i-];
  37. for(i=n-; i>=; i--) sa[--wsf[wv[i]]]=y[i];
  38. t=x;
  39. x=y;
  40. y=t;
  41. x[sa[]]=;
  42. for(p=,i=; i<n; i++)
  43. x[sa[i]]=cmp(y,sa[i-],sa[i],j)? p-:p++;
  44. }
  45. }
  46. void getheight(int *r,int n)//n不保存最后的0
  47. {
  48. int i,j,k=;
  49. for(i=; i<=n; i++) rank[sa[i]]=i;
  50. for(i=; i<n; i++)
  51. {
  52. if(k)
  53. k--;
  54. else
  55. k=;
  56. j=sa[rank[i]-];
  57. while(r[i+k]==r[j+k])
  58. k++;
  59. height[rank[i]]=k;
  60. }
  61. }
  62.  
  63. char str[N],ans[N];
  64. int id[N],vis[];
  65.  
  66. bool check(int mid,int n,int k)
  67. {
  68. int i,j,cnt = ;
  69. memset(vis,,sizeof(vis));
  70. for(i = ; i<=n; i++)
  71. {
  72. if(height[i]<mid)
  73. {
  74. memset(vis,,sizeof(vis));
  75. cnt = ;
  76. continue;
  77. }
  78. if(!vis[id[sa[i-]]])
  79. {
  80. cnt++;
  81. vis[id[sa[i-]]] = ;
  82. }
  83. if(!vis[id[sa[i]]])
  84. {
  85. cnt++;
  86. vis[id[sa[i]]] = ;
  87. }
  88. if(cnt == k)
  89. {
  90. for(j = ; j<mid; j++)
  91. ans[j] = s[sa[i]+j];
  92. ans[mid] = '\0';
  93. return ;
  94. }
  95. }
  96. return ;
  97. }
  98.  
  99. int main()
  100. {
  101. int n,i,j,k,len;
  102. while(~scanf("%d",&k),k)
  103. {
  104. n = ;
  105. for(i = ; i<k; i++)
  106. {
  107. scanf("%s",str);
  108. len = strlen(str);
  109. for(j = ; j<len; j++)
  110. {
  111. s[n] = str[j];
  112. id[n] = i;
  113. n++;
  114. }
  115. s[n] = '#'+i;
  116. id[n] = '#'+i;
  117. n++;
  118. }
  119. s[n] = ;
  120. getsa(s,sa,n+,);
  121. getheight(s,n);
  122. int l = ,r = len,mid,flag = ;
  123. while(l<=r)
  124. {
  125. mid = (l+r)/;
  126. if(check(mid,n,k))
  127. {
  128. flag = ;
  129. l=mid+;
  130. }
  131. else
  132. r=mid-;
  133. }
  134. if(flag)
  135. printf("%s\n",ans);
  136. else
  137. printf("IDENTITY LOST\n");
  138. }
  139.  
  140. return ;
  141. }

poj 3450 Corporate Identity的更多相关文章

  1. POJ 3450 Corporate Identity(KMP)

    [题目链接] http://poj.org/problem?id=3450 [题目大意] 求k个字符串的最长公共子串,如果有多个答案,则输出字典序最小的. [题解] 我们对第一个串的每一个后缀和其余所 ...

  2. POJ 3450 Corporate Identity (KMP,求公共子串,方法很妙)

    http://blog.sina.com.cn/s/blog_74e20d8901010pwp.html我采用的是方法三. 注意:当长度相同时,取字典序最小的. #include <iostre ...

  3. POJ 3450 Corporate Identity kmp+最长公共子串

    枚举长度最短的字符串的所有子串,再与其他串匹配. #include<cstdio> #include<cstring> #include<algorithm> #i ...

  4. POJ 3450 Corporate Identity (KMP+暴搞)

    题意: 给定N个字符串,寻找最长的公共字串,如果长度相同,则输出字典序最小的那个. 找其中一个字符串,枚举它的所有的字串,然后,逐个kmp比较.......相当暴力,可二分优化. #include & ...

  5. POJ 3450 Corporate Identity KMP解决问题的方法

    这个问题,需要一组字符串求最长公共子,其实灵活运用KMP高速寻求最长前缀. 请注意,意大利愿父亲:按照输出词典的顺序的规定. 另外要提醒的是:它也被用来KMP为了解决这个问题,但是很多人认为KMP使用 ...

  6. POJ 题目3450 Corporate Identity(KMP 暴力)

    Corporate Identity Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5493   Accepted: 201 ...

  7. poj 3518 Corporate Identity 后缀数组->多字符串最长相同连续子串

    题目链接 题意:输入N(2 <= N <= 4000)个长度不超过200的字符串,输出字典序最小的最长公共连续子串; 思路:将所有的字符串中间加上分隔符,注:分隔符只需要和输入的字符不同, ...

  8. 字符串截取模板 && POJ 3450、3080 ( 暴力枚举子串 && KMP匹配 )

    //截取字符串 ch 的 st~en 这一段子串返回子串的首地址 //注意用完需要根据需要最后free()掉 char* substring(char* ch,int st,int en) { ; c ...

  9. POJ - 3450

    题目链接:http://poj.org/problem?id=3450 Corporate Identity Time Limit: 3000MS   Memory Limit: 65536K Tot ...

随机推荐

  1. JRE 和 JDK 的区别是什么?

    JRE: Java Runtime Environment JDK:Java Development Kit JRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库.是使用java ...

  2. 修改VISUAL STUDIO EXPRESS 2012新建C++文件编码

    本站文章除注明转载外,均为本站原创或者翻译. 本站文章欢迎各种形式的转载,但请18岁以上的转载者注明文章出处,尊重我的劳动,也尊重你的智商: 本站部分原创和翻译文章提供markdown格式源码,欢迎使 ...

  3. Javascript面向对象研究心得

    这段时间正好公司项目须要,须要改动fullcalendar日历插件,有机会深入插件源代码.正好利用这个机会,我也大致学习了下面JS的面向对象编程,感觉收获还是比較多的. 所以写了以下这篇文章希望跟大家 ...

  4. KVM虚拟机介绍

    一 KVM虚拟机简介 kernel-based Virtual Machine的简称,是一个开源的 系统虚拟化模块,自Linux 2.6.20之后集成在Linux的各个主要发行版本中.它使用Linux ...

  5. K&amp;R练习题6-1统计关键词出现的次数

    这道练习题训练了: 1.结构体数组 2.二分查找 3.指针操作 ---- 都不难.但非常基础,我认为非常好,做完了记到博客上来,题目见k&R,实现例如以下: /* * Practice of ...

  6. MySql连接问题

    今天想通过命令连接到另外一台主机的Mysql 命令: mysql -h ip -u username -p EnterPassWord: password 连接成功

  7. MFC常用控件CListCtrl 、CSliderCtrl、CToolTipCtrl、CTreeCtrl的自绘

    Window平台下MFC提供的CListCtrl .CSliderCtrl.CToolTipCtrl.CTreeCtrl等控件大多时候是不能满足我们的需求,如果我要在改变滑动条的颜色,我要改变滑动条的 ...

  8. 简单区分`:before`与`::before`的区别

    简单区分:before与::before的区别 :hover我们都知道,称作伪类,英文名pseudo-class,而我们此处提到的:before以及:after也是伪类,属于css2的内容,在ie8下 ...

  9. 【linux】内核编译

    原创,转载时请注明,谢谢.邮箱:tangzhongp@163.com 博客园地址:http://www.cnblogs.com/embedded-tzp Csdn博客地址:http://blog.cs ...

  10. PHP 页面跳转到另一个页面的几种方法分享

    如何在 PHP 中从一个页面重定向到另外一个页面呢?今天 清源 为大家列举出了三种办法,供大家来参考. 一.用HTTP头信息  也就是用PHP的HEADER函数.PHP里的HEADER函数的作用就是向 ...