HDU 1238 Substrings(求公共正反向连续子串)

本文介绍了一道关于寻找多个字符串中最大公共子串的问题,并提供了一个详细的算法实现过程。该算法首先找出最短字符串作为基准,然后通过两层循环来枚举所有可能的子串长度和起始位置,验证这些子串是否存在于其他字符串中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Substrings

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 8504 Accepted Submission(s): 3931


Problem Description
You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings.

Input
The first line of the input file contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains a single integer n (1 <= n <= 100), the number of given strings, followed by n lines, each representing one string of minimum length 1 and maximum length 100. There is no extra white space before and after a string.

Output
There should be one line per test case containing the length of the largest string found.

Sample Input
2 3 ABCD BCDFF BRCD 2 rose orchid

Sample Output
2 2

Author
Asia 2002, Tehran (Iran), Preliminary

//优化 
#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
using namespace std;
const int N=100+10;
int n,id,re,ilen;
char c[N][N];
int len[N];
int main(){
	int t,i,small,j,k,z,zz;
	bool ok;
	scanf("%d",&t);
	while(t--){
		re=0;
		small=N;
		scanf("%d",&n);
		for(i=0;i<n;i++){
		   	scanf("%s",c[i]);
		   	len[i]=strlen(c[i]);
		   	if(len[i]<small)
		   	  {
		   	  	small=len[i];
		   	  	id=i;
			}
		}
		ilen=len[id];
		for(i=ilen;re==0&&i>0;i--){   //枚举子串长度
		   for(j=0;re==0&&j+i-1<ilen;j++){   //枚举模板字串的起始点 
		for(k=0;k<n;k++){
			if(k==id)
			continue;
			ok=0;
			for(z=0;z+i-1<len[k];z++) {  //从左开始 
			   for(zz=0;zz<i;zz++){
			   	   if(c[k][z+zz]!=c[id][j+zz])
			   	     break;
			   }
			   if(zz==i){
			   	ok=1;
			   	break;
			   }		  
		}	
		for(z=len[k]-1;!ok&&z-i+1>=0;z--) {  //从右开始 
			   for(zz=0;zz<i;zz++){
			   	   if(c[k][z-zz]!=c[id][j+zz])
			   	     break;
			   }
			   if(zz==i){
			   	ok=1;
			   	break;
			   }		  
		}
		  if(!ok)
		    break;	
		} 
		  if(k==n){
		  	re=i;
		  	break;
		  }		  
		} 	
} 
   	printf("%d\n",re);
}
	return 0;
}



/*哎呀   循环放错了   不过AC了 
#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
const int N=100+10;
int n,id,re,ilen,rlen;
char c[N][N];
int len[N];
int main(){
	int t,i,small,j,k,z,zz;
	bool ok;
	scanf("%d",&t);
	while(t--){
		re=0;
		rlen=0;
		small=N;
		scanf("%d",&n);
		for(i=0;i<n;i++){
		   	scanf("%s",c[i]);
		   	len[i]=strlen(c[i]);
		   	if(len[i]<small)
		   	  {
		   	  	small=len[i];
		   	  	id=i;
			}
		}
		ilen=len[id];
		for(i=0;i<ilen;i++){  //枚举模板字符串的字符起始位置
		   for(j=ilen-i;i+j-1<ilen&&j>0;j--) {    //子串的长度 
		      for(k=0;k<n;k++){   //枚举每个字符串 
		         if(k==id)
		        continue;
		      	  ok=0;
				for(z=0;z+j-1<len[k];z++){ //左开始的位置 
					for(zz=0;zz<j;zz++)  //每个字符比较 
					{
					    if(c[k][z+zz]!=c[id][i+zz])
						break;	
					}			
				  if(zz==j)
				   {
				      ok=1;
					  break;	
				   }		    
			  }
			  for(z=len[k]-1;!ok&&z-j+1>=0;z--){  //从右开始 
			  		for(zz=0;zz<j;zz++)
					{
					   	if(c[k][z-zz]!=c[id][i+zz])
						break;	
					}   
				   if(zz==j)
				   {
				      ok=1;
					  break;	
				   }	
			  } 
			  if(!ok)   //有一个不行 这个子串就不行了 
			  break;		  
		}
		if(k==n)
		{
		//坑了好久 枚举的起点放在长度外面了 造成被更新了...日了狗了 
			re=max(re,j);  
			break;
		 } 
}
}  
      printf("%d\n",re); 
}
	return 0;
}
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值