1. 程式人生 > >dfs(洛谷1019 單詞接龍NOIp2000提高組第三題)

dfs(洛谷1019 單詞接龍NOIp2000提高組第三題)

單詞 turn space != tac std 例如 關系 一行

單詞接龍是一個與我們經常玩的成語接龍相類似的遊戲,現在我們已知一組單詞,且給定一個開頭的字母,要求出以這個字母開頭的最長的“龍”(每個單詞都最多在“龍”中出現兩次),在兩個單詞相連時,其重合部分合為一部分,例如 beast和astonish,如果接成一條龍則變為beastonish,另外相鄰的兩部分不能存在包含關系,例如at 和 atide 間不能相連。

輸入格式:

輸入的第一行為一個單獨的整數n (n<=20)表示單詞數,以下n 行每行有一個單詞,輸入的最後一行為一個單個字符,表示“龍”開頭的字母。你可以假定以此字母開頭的“龍”一定存在.

輸出格式:

只需輸出以此字母開頭的最長的“龍”的長度

輸入樣例#1:
5
at
touch
cheat
choose
tact
a
輸出樣例#1:
23           (連成的“龍”為atoucheatactactouchoose)   
思路就是爆搜啦,審題清楚後代碼就很容易完成了~
#include<bits/stdc++.h>
using namespace std;
int ans=0,n;
int book[50];
string s[50];
char  str;
int now;

void dfs(int num)
{
	ans=max(ans,now);
	int len=s[num].length();
	char las=s[num][len-1];
	for(int i=1;i<=n;i++)
		if(book[i]<2)
		{
		  int len2=s[i].length();
		  //cout<<len2<<endl;
			for(int j=0;j<len2;j++)
				if(s[i][j]==las)
				{
					int ok=0;
					for(int k=j-1,point=1;k>=0;k--,point++)
					{
						if(len-point-1<0) break;
						if(s[i][k]!=s[num][len-point-1])
						{ok=1;break;}
					}
					if(!ok)
					{
						book[i]++;
						now+=(len2-j-1);
						dfs(i);
						book[i]--;
						now-=(len2-j-1);
					}
				}
		}
}

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	    cin>>s[i];
	cin>>str;
	for(int i=1;i<=n;i++)
	{
		if(s[i][0]==str)
		{
			now=s[i].length();
			memset(book,0,sizeof(book));
			book[i]++;
			dfs(i);
		}
	}
	cout<<ans<<endl;
	return 0;
}

  

dfs(洛谷1019 單詞接龍NOIp2000提高組第三題)