C++搜索与回溯算法之单词接龙

----------------------*单词接龙*----------------------

Description

单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如beastastonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如atatide间不能相连。

Input

输入的第一行为一个单独的整数n(n<=20)表示单词数,以下n行每行有一个单词(只含有大写或小写字母,长度不超过20),输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在。

Output

只需输出以此字母开头的最长的“龙”的长度。

Sample Input

5
at
touch
cheat
choose
tact
a

Sample Output

23

思路解析

1.依鄙人之拙见,这道题使用字符串(string)比字符数组要好,因为字符串类可以用"substr"进行取子串。

2.不能把字符串们接起来,例如:输入"drive veget vegetable",接起来就会出错。所以只能把长度进行加减。

3.每个"单词"能使用两次,所以flag不可以定义为bool类型。

4.描述中"相邻的两部分不能存在包含关系"可以不管,包含的话也没太大关系,只会让你因此乱了阵脚。

5.如果深搜函数中的内层循环没有break过的话,就说明没法"接龙",就跳过该次循环(注意:是该次,不是该个)。

6.不用解释伟大的万能头文件bits/stdc++.h了吧。

代码

#include"bits/stdc++.h"
using namespace std;
int n,maxx;
struct node{
	string str;
	int len;
	int flag;
}word[100];
void search(string x,int sum)
{
	for(int i=1;i<=n;i++)
		if(word[i].flag<2)
		{
			int a,j;
			for(j=x.length()-1;j>=0;j--)
				if(x.substr(j,x.length()-j)==word[i].str.substr(0,x.length()-j))
				{
					a=x.length()-j;
					break;
				}
			if(j==-1) continue;
			word[i].flag++;
			sum+=word[i].str.length()-a;
			search(word[i].str,sum);
			if(sum>maxx) {maxx=sum;}
			sum-=word[i].str.length()-a;
			word[i].flag--;
		}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		cin>>word[i].str;
		word[i].len=word[i].str.length();
	}
	string wxy;
	cin>>wxy;
	search(wxy,1);
	printf("%d",maxx);
}


你可能感兴趣的:(深度优先搜索,错题大总结,搜索算法刷题集锦)