NOIP2000提高組 單詞接龍

NOIP2000提高組 單詞接龍

題目描述

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

輸入輸出格式

    輸入格式:

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

    輸出格式:

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

輸入輸出樣例

    輸入樣例:

    5
    at
    touch
    cheat
    choose
    tact
    a

    輸出輸出樣例

    23
    輸出樣例說明:連成的“龍”爲atoucheatactactouchoose

解題分析

    由於單詞個數不超過20,因此可以通過回溯法嘗試所有情況。

    在進行回溯法之前先做預處理,即確定每兩個單詞之間是否能連接,如果能連接,則記錄交叉的長度。該長度也被用於在進行兩個單詞連接時計算總長度。

#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
#define N 22
string words[N];
int n, relation[N][N], used[N] = {0}, ans[2*N], ans1[2*N], result = 0, de;
// 計算兩個單詞之間的交叉情況,x在前,y在後,返回交叉長度 
int re(int x, int y){
	string str1 = words[x], str2 = words[y];
	int i, j, k, len1 = str1.size(), len2 = str2.size();	
	for(k=1; k<=min(len1, len2); k++){
		for(i=0; i result){
		result = len;
		de = depth;
		for(i=0; i<=depth; i++){  // 記錄字符串如何連接,可以忽略 
			ans[i] = ans1[i];  			
		}
	}	
	for(i=1; i<=n; i++){
		if(relation[k][i]>0 && used[i]<2){
			len += words[i].size() - relation[k][i];  // 當前長度 
			used[i]++;
			ans1[depth] = i;
			dfs(i, depth+1, len);
			len -= words[i].size() - relation[k][i];
			used[i]--;
		}
	}	
}

int main(){
	ios::sync_with_stdio(false);
	int i, j;
	cin>>n;
	for(i=1; i<=n; i++)
		cin>>words[i];
	cin>>words[0];
	init();		
	ans1[0] = 0;
	dfs(0, 1, 1);	
	cout<

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章