noip2000提高組 單詞接龍

題目描述

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

輸入輸出格式

輸入格式:

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

輸出格式:

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

輸入輸出樣例

輸入樣例#1:
5
at
touch
cheat
choose
tact
a
輸出樣例#1: 
23





說明

(連成的“龍”爲atoucheatactactouchoose)

NOIp2000提高組第三題


思路:

dfs找最大長度。有一個初始化,得到每兩個單詞的最大重合長度(很重要,在搜索中需要減去重合部分),dfs就是很普通啦!


代碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>

using namespace std;

string str[50];
int n, ans = -1, an;
int vis[50], re[50][50];
char ch;

int haha( int x, int y ) { 	//求單詞x與y的最大重合長度
	int cnt = 0;
	bool book = true;
	for( int i = str[x].size() - 1; i >= 0; i-- ) {	//從後到前枚舉如果後面的字母都沒重合前面更不可能重合。
		for( int j = i; j < str[x].size(); j++ ) //從i這個位置向後枚舉,判斷重合
			if( str[x][j] != str[y][cnt++] ) {
				book = false;	//不重合
				break;
			}
		if( book ) //如果有重合,返回重合的長度(總長度減去重合位置向後的長度)
			return str[x].size() - i;
		//因爲要重複調用,都要重新賦爲0 。
		cnt = 0; 
		book = true;
	}
	return 0;
}

void dfs( int x ) { //搜索
	bool book = false;
	for( int i = 1; i <= n; i++ ) {
		if( vis[i] >= 2 ) continue; //單詞i如果重複使用兩次那就不行
		if( re[x][i] == str[x].size() || re[x][i] == str[i].size() ) continue; //如果兩個單詞相同或包含也不行
		if( re[x][i] == 0 ) continue; //沒有重合的部分沒法接在一起
		an += str[i].size() - re[x][i];	//接在一起
		vis[i]++; //i的使用次數+1
		book = true; //找到可以相接的單詞
		dfs( i ); 
		an -= str[i].size() - re[x][i]; //回溯
		vis[i]--;	
	}
	if( book == false ) { //找不到可以接的單詞了
		ans = max( ans, an );
		return;
	}
}

int main() {
	scanf( "%d", &n );
	for( int i = 1; i <= n; i++ )
		cin>>str[i];
	cin>>ch;
	for( int i = 1; i <= n; i++ )
		for( int j = 1; j <= n; j++ )
			re[i][j] = haha( i, j ); //初始化每兩個單詞重合的長度
	for( int i = 1; i <= n; i++ ) {
		if( str[i][0] == ch ) { //找到首字母是ch的單詞
			an = str[i].size();
			vis[i]++;
			dfs( i );
			vis[i] = 0;
		}
	}
	printf( "%d", ans );
	return 0;
}

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