题目链接: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 }
时间: 2024-10-12 18:09:06