[NOIP2000]单词接龙

题目了链接:http://www.rqnoj.cn/Problem_608.html

题目数据量不是很大,直接深度搜索即可。首先建立一个图,用于存储任意两个单词之间的关系,如果是一个单词中的若干尾字符是另一单词的前缀,则存储其公共长度。由于每个单词可用两次,所以需要用一个数组来记录使用情况。

代码如下:

#include
#include
#include

using namespace std ;
const int maxn = 25 ;

int map[maxn][maxn] ;
int n ;
char str[maxn][maxn] ;
int visit[maxn] ; 
int cont ;

char c ;

void build() ;

int dfs(int) ;

int main()
{
 	 scanf("%d" , &n) ;
 	 int i ;

 	 
 	 for(i = 0 ; i < n ; i ++)
 	 {
	  		 scanf("%s" , &str[i]) ;
	 }
	 getchar() ;
 	 scanf("%c" , &c) ;
 	 
 	 build() ;
 	 cont = 0 ;
 	 int temp ;
 	 
 	 for(i = 0 ; i < n ; i++)
 	 {
	  		 if(str[i][0]==c)
	  		 {
				  visit[i] -- ;
				  temp = dfs(i) ;
				  
				  if(temp > cont)
  			 	  			 cont = temp ;
  			 	  visit[i] ++ ;			 
	  		 }
	 }
 	 printf("%d\n" , cont) ;
 	 return 0 ;
}

void build()
{
 	  memset(map , 0 , sizeof(map)) ;
 	  
 	  int i ;
 	  int j ;
 	  int k ;
 	  int len1 ;
 	  int len2 ;
 	  
 	  for(i = 0 ; i < n ; i ++)
 	  {
	  		  for(j = 0 ; j < n ; j ++)
	  		  {
				  len1 = strlen(str[i]) ;
				  len2 = strlen(str[j]) ;
			  		 for(k = 0 ; k <= len1 && k <= len2 ; k ++)
					 {
					  		 if(strncmp(str[i] + len1 - k - 1 , str[j] ,  k + 1)==0)
					  		 {
										map[i][j] = k + 1 ;
							  			break ;		 
		  					 }
	  		 		 }
	  		  }
	  }
	  
	  for(i = 0 ; i < n ; i ++)
	  {
	  		  visit[i] = 2 ;
	  }
 	  
}

int dfs(int s)
{
 	 int i ;
 	 int temp ;
 	 int max_len ;
 	 max_len = 0 ;
	 bool t = 0  ;
 	 
 	 for(i = 0 ; i < n ; i ++)
 	 {
		     temp = 0 ;

	  		 if(map[s][i] && visit[i])
	  		 {
				  t = 1 ;
				  visit[i]-- ;
				  temp = dfs(i) ;
				  visit[i] ++ ; 
				  temp = temp + strlen(str[s]) - map[s][i] ;
	  		 }
	  		 if(temp > max_len)
	  		 			max_len = temp ;
	 }
	 
	 if(!t)
	 {
		 return strlen(str[s]) ;
	 }
	 
	 
	 return max_len ;
}


你可能感兴趣的:(搜索)