HDU2328 (暴力KMP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2328

题意:输入一个不为0的整数n,再输入n个字符串,求n个字符串的最长公共连续子序列,并保证字典序最小。

题解:直接暴力枚举。

Times:764ms

Memory:1892KB

代码如下:

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 const int maxn = 205;
  7 char s[4005][maxn];
  8 char T[maxn];
  9 char t[maxn];
 10 int Next[maxn];
 11 void getcha(int len,int pos,char *s1)
 12 {
 13     for(int i=0,j=pos;i<len;i++,j++)
 14     {
 15         t[i]=s1[j];
 16     }
 17 //    cout<<t<<endl;
 18 }
 19 void getNext(int len)
 20 {
 21     int i=0,j=-1;
 22     Next[0]=-1;
 23     while(i<len)
 24     {
 25         if(j==-1||t[i]==t[j])
 26             i++,j++,Next[i]=j;
 27         else
 28             j=Next[j];
 29     }
 30 }
 31 int find(char *s1, int len1,int len2)
 32 {
 33     int i=0,j=0;
 34     while(i<len1&&j<len2)
 35     {
 36         if(j==-1||s1[i]==t[j])
 37         i++,j++;
 38         else
 39         j=Next[j];
 40         if(j==len2)
 41             return 1;
 42     }
 43     return 0;
 44 }
 45 int main()
 46 {
 47     int n;
 48     while(~scanf("%d",&n)&&n)
 49     {
 50         int leni[4005]; //统计所有字符串的长度
 51         int len=300,te=0;
 52         for(int i=0;i<n;i++)
 53         {
 54             scanf("%s",s[i]);
 55             if(strlen(s[i])<len) //找出最短的字符串
 56             {
 57                 len=strlen(s[i]);
 58                 te = i;
 59             }
 60         }
 61         for(int i=0;i<n;i++)
 62             leni[i]=strlen(s[i]);
 63         int kk=0,kkk=0;
 64         int temp1=0,temp2=-1,temp3; //temp1用来标记该长度是否可以全部匹配,temp2用来记录长度。
 65         for(int i=len;i>0;i--)//代表所需子串的长度
 66         {
 67             memset(t,0,sizeof(t));
 68             for(int j=len-i;j>=0;j--)//该长度的所有串 ,j代表起始 位置
 69             {
 70                 temp1=0;
 71                 getcha(i,j,s[te]);//得到需要匹配的串
 72                 getNext(i);
 73                 for(int k=0;k<n;k++)
 74                 {
 75                     if(k!=te)
 76                     {
 77                         temp1=find(s[k],leni[k],i);
 78                         if(temp1==0)
 79                         {
 80                             break;
 81                         }
 82                     }
 83                 }
 84                 if(temp1)
 85                 {
 86                     kkk=1;
 87                             if(!kk)
 88                             {
 89                                 strcpy(T,t);
 90                                 kk=1;
 91                             }
 92                             else
 93                             {
 94                                 if(strcmp(t,T)<0)
 95                                 {
 96                                     memset(T,0,sizeof(T));
 97                                     strcpy(T,t);
 98                                 }
 99                             }
100                 }
101             }
102         if(kkk==1)
103         break;
104     }
105         if(kkk==0)
106         cout<<"IDENTITY LOST"<<endl;
107         else
108             cout<<T<<endl;
109     }
110 } 
时间: 2024-11-10 15:18:39

HDU2328 (暴力KMP)的相关文章

hdu2087 剪花布条 暴力/KMP

在字符串中不可重叠地寻找子串数量,暴力/KMP 1 #include<stdio.h> 2 #include<string.h> 3 4 int main(){ 5 char a[1005],b[1005]; 6 while(scanf("%s",a)!=EOF&&a[0]!='#'){ 7 scanf("%s",b); 8 getchar(); 9 int la=strlen(a),lb=strlen(b); 10 int

bzoj 3620 暴力KMP

十分暴力的KMP,枚举左端点,在向右侧推进的同时,取较小的la保证条件,n方暴力 #include<bits/stdc++.h> #define rep(i,j,k) for(int i=j;i<=k;i++) #define inf 0x3fffffff using namespace std; const int N=20000; char s[N];int l,k,nxt[N],la[N],ans; int main(){ freopen("3620.in",&

CF701F String set queries (分块思想+暴力)

很容易想到AC自动机,但是却发现不怎么支持删除 完蛋,怎么办? 思考如何优化暴力 有两种暴力:一种是kmp,一种是trie trie时间复杂度优秀,但空间不行: kmp时间不行 那么我们可以互补一下 对于长度小于 \(sqrt\) 的,我们加入 \(trie\) 中,否则暴力 \(kmp\),这样能够维持时间复杂度,因为总长不大 分块思想真妙! #include <map> #include <set> #include <ctime> #include <que

bzoj3620

KMP 我似乎复杂度写的不对... 因为位置相同只算一次,后缀数组什么的都不管用了,我们就暴力kmp,但是我写的是暴力跳...竟然过了...我写bzoj3670才发现... #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 15010; int n, k, ans; int nxt[N]; char s[N]; void kmp(char *

(Incomplete) UVa 10298 Power Strings

方法:暴力 / kmp 先说一下暴力的方法,就是尝试把原来的string不断分割,在substring 里求解.code 如下 #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <string> #include <vector> #include <stack> #include <bitse

Match:Blue Jeans(POJ 3080)

DNA序列 题目大意:给你m串字符串,要你找最长的相同的连续字串 这题暴力kmp即可,注意要按字典序排序,同时,是len<3才输出no significant commonalities 1 #include <iostream> 2 #include <functional> 3 #include <algorithm> 4 #include <string.h> 5 #define MAX 60 6 7 using namespace std; 8

P4824 [USACO15FEB]Censoring (Silver) 审查(银)

传送门 一个串的匹配肯定考虑KMP 那就暴力KMP 记录一下到每个字符时匹配的位置 找到一个符合的串就标记然后暴力回跳 感觉好像太暴力了... #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int N=1e6+7; char ch[N],a[N]; int f[

hdu-2328(暴力枚举+kmp)

题意:给你n个字符串,问你这n个串的最长公共子串 解题思路:暴力枚举任意一个字符串的所有子串,然后暴力匹配,和hdu1238差不多的思路吧,这里用string解决的: 代码: #include<iostream> #include<string> #include<cstdio> #include<algorithm> using namespace std; string t; int main() { int n; string a[4050]; ios

hdu2328 Corporate Identity【string库使用】【暴力】【KMP】

Corporate Identity Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3308    Accepted Submission(s): 1228 Problem Description Beside other services, ACM helps companies to clearly state their "cor