码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1238 (暴力反转KMP)

时间:2015-07-17 18:00:48      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:

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

题意:给定n个字符串,求它们的最长连续子序列,值得注意的是,求的的子序列可以是反转的。

题解:直接记录出最短的字符串作为匹配串,其实用第一个也应该是可以的,然后不断的缩小其长度,知道能够匹配成功,如果匹配不成功,则把字符串反转,再找一次即可。

Time:31ms

Memory:1712KB

reverse(s,s+n):字符串反转函数。

代码如下:

技术分享
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 const int maxn = 105;
  7 char s[maxn][maxn];
  8 char t[maxn],f[maxn];
  9 int Next[maxn];
 10 void getcha(int len,int pos,char *s1)
 11 {
 12     for(int i=0,j=pos;i<len;i++,j++)
 13     {
 14         t[i]=s1[j];
 15     }
 16 //    cout<<t<<endl;
 17 }
 18 void getNext(int len)
 19 {
 20     int i=0,j=-1;
 21     Next[0]=-1;
 22     while(i<len)
 23     {
 24         if(j==-1||t[i]==t[j])
 25             i++,j++,Next[i]=j;
 26         else
 27             j=Next[j];
 28     }
 29 }
 30 int find(char *s1, int len1,int len2)
 31 {
 32     int i=0,j=0;
 33     while(i<len1&&j<len2)
 34     {
 35         if(j==-1||s1[i]==t[j])
 36         i++,j++;
 37         else
 38         j=Next[j];
 39         if(j==len2)
 40             return 1;
 41     }
 42     return 0;
 43 }
 44 int main()
 45 {
 46     int test;
 47     cin>>test;
 48     while(test--)
 49     {
 50         int leni[maxn]; //统计所有字符串的长度 
 51         int n,len=200,te=0;
 52         scanf("%d",&n);
 53         for(int i=0;i<n;i++)
 54         {
 55             scanf("%s",s[i]);
 56             if(strlen(s[i])<len) //找出最短的字符串 
 57             {
 58                 len=strlen(s[i]);
 59                 te = i;
 60             }
 61         }
 62         for(int i=0;i<n;i++)
 63             leni[i]=strlen(s[i]);
 64         int temp1=0,temp2=-1; //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                             reverse(s[k],s[k]+leni[k]);
 81                             temp1=find(s[k],leni[k],i);
 82                             if(temp1==0)
 83                             {
 84                                 reverse(s[k],s[k]+leni[k]);
 85                                 break;
 86                             }
 87                             reverse(s[k],s[k]+leni[k]);
 88                             if(temp1==0)
 89                                 break;
 90                         }
 91                     }
 92                 }
 93             if(temp1==1)
 94             {
 95                 temp2=i;
 96                 break;
 97             }
 98         }
 99         if(temp1==1)
100         break;
101     }
102         if(temp2==-1)
103         cout<<"0"<<endl;
104         else
105         cout<<temp2<<endl;
106         
107     }
108 } 
View Code

 

HDU 1238 (暴力反转KMP)

标签:

原文地址:http://www.cnblogs.com/ikids/p/4654772.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!