P1019 Word Solitaire (dfs+simple string processing)

Insert picture description hereInsert picture description here
Question meaning:
1. Give n words, and then according to the rules on the question, ensure that each word given appears at most 2 times in "Dragon";
2. Each adjacent connected word cannot have a containment relationship (but I To be honest, what is the maximum length of the word eye? The answer is actually 5.... Is eye not a subset of eye? Why this is not included, so my judge calculates the length wrong);
3. Follow The single-character word given at the end serves as the leader.
What is the length of the longest concatenated string?
Obviously, this question will be OK directly with dfs. One difficulty lies in how to find the length of the connection; just
enumerate directly;
AC code:

#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;
}

Guess you like

Origin blog.csdn.net/qq_44555205/article/details/104128531