P1019 单词接龙(dfs+简单的字符串处理)

在这里插入图片描述在这里插入图片描述
题意:
1.给出n个单词,然后根据题上的规则保证给出的每个单词在“龙"中最多出现2次;
2.每个相邻连接的单词不能存在包含关系(但是我说实话eye这个单词你说最大长度是多少?答案居然给的5。。。。eye不是eye的子集吗?怎么这也不算包含,搞得我judge算长度算错了);
3.按照最后给出的单个字符的单词作为龙头.
问连接出来的最长的字符串长度是多少?
很明显这道题直接dfs一下就OK了,有个难点在于如何求连接的长度;
直接枚举即可;
AC代码:

#include<bits/stdc++.h>
using namespace std;
int book[50];
string s[50];
int ans;
int n;
int judge(string s1,string s2){
    
    //枚举,定s1,从后面开始枚举
	int res=0;
	  int len1=s1.length(),len2=s2.length();
	  for(int i=len1-1;i>=0;i--){
    
    
	  	  if(s1[i]==s2[0]){
    
    
	  	  	  int j,k,t=0;
	  	  	  for(j=i,k=0;j<len1&&k<len2;j++,k++){
    
    
	  	  	  	         if(s1[j]==s2[k])t++;
	  	  	  	         else break;
				  }
				  if(j==len1){
    
    
				  	res=max(res,t);break;//这里需要break;因为以防eye这种单词出现因为eyeye 可以拼接
				  }
			}
	  }
	  return res;
}
void dfs(int fr,int len){
    
    //这里可以把dfs当做一个节点,存的是先前的单词和长度
	  	 ans=max(ans,len);//每次记录最大值
	  for(int i=0;i<2*n;i++){
    
    //枚举其他的没有被标记的单词
	  	if(!book[i]){
    
    //如果没有被标记
	  	   	    int t=judge(s[fr],s[i]);//求当前的单词和先前的单词重合的长度
	  	   	    if(t==s[fr].length()||t==s[i].length()||t==0)continue;//如果存在包含关系,或者不包含,那么就不用标记
	  	   	    else {
    
    
	  	   	    	    book[i]=1;
	  	   	    	    dfs(i,len+s[i].length()-t);//向下搜索,这里的len是前面已经拼好的单词的字符串长度,这里传下去的是拼好s[i]这个字符串之后的长度
	  	   	    	    book[i]=0;
					}
			 }
	  }
}
int main(){
    
    
	scanf("%d",&n);
	for(int i=0;i<n;i++){
    
    
		 cin>>s[i];
	}
	for(int i=n;i<2*n;i++){
    
    //因为说最多两次,所以我复制一次
		   s[i]=s[i-n];
	}
	char c;
	cin>>c;
	for(int i=0;i<2*n;i++){
    
    //枚举每个单词
		if(s[i][0]==c&&!book[i]){
    
    //这个单词没有被标记过
			book[i]=1;
		 dfs(i,s[i].length());//表示当前选已经的这个单词的下标i和单词的长度
	        book[i]=0;
	   }
	}
	printf("%d\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44555205/article/details/104128531

相关文章