题目描述
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。
输入输出格式
输入格式:
输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.
输出格式:
只需输出以此字母开头的最长的“龙”的长度
输入输出样例
说明
(连成的“龙”为atoucheatactactouchoose)
NOIp2000提高组第三题
1 #include <iostream> 2 #include <string> 3 #include <cstdio> 4 #include <algorithm> 5 #include <stdlib.h> 6 7 using namespace std; 8 const int maxn = 50; 9 string word[maxn]; 10 int flag[maxn], n;//已遍历为1 11 char head; 12 int con1[maxn][maxn];//存储当两个词有序连接的时候,第一个词的衔接点是第几个字母 13 int maxlen = 0, tmplen = 0; 14 15 void connect() { 16 for (int i = 1; i <= 2 * n; i++) 17 for (int j = 1; j <= 2 * n; j++) { 18 if (((word[i].find(word[j])<999&&word[i].find(word[j]) >=0) || (word[j].find(word[i])<999) && word[j].find(word[i]) >= 0) && word[i] != word[j]) 19 continue; 20 int l = word[j].length(),_l=word[i].length(); 21 for (int k = 1; k<l; k++) { 22 int tmp = word[i].rfind(word[j].substr(0,k)); 23 if (tmp<999&&tmp>=0&&(_l-tmp)==k) 24 { 25 con1[i][j] = tmp; 26 break; 27 } 28 } 29 } 30 } 31 32 void dfs(int h) { 33 for (int i = 1; i <= 2 * n; i++) { 34 if (!flag[i] && con1[h][i]) { 35 flag[i] = 1; 36 int l1 = word[h].length(), l2 = word[i].length(); 37 int addlen = -(l1 - con1[h][i] - 1) + l2 - 1; 38 tmplen += addlen; 39 maxlen = max(tmplen, maxlen); 40 dfs(i); 41 tmplen -= addlen; 42 flag[i] = 0; 43 } 44 } 45 } 46 47 int main() 48 { 49 scanf("%d", &n); 50 for (int i = 1; i <= n; i++) { 51 cin >> word[i]; 52 word[n + i] = word[i]; 53 } 54 scanf("%s", &head); 55 connect(); 56 for (int i = 1; i <= n; i++) { 57 if (word[i][0] == head) 58 { 59 flag[i] = 1; 60 tmplen = word[i].length(); 61 maxlen = max(tmplen, maxlen); 62 dfs(i); 63 flag[i] = 0; 64 } 65 } 66 printf("%d\n", maxlen); 67 return 0; 68 }
WA1:泪奔!
看成只要两个词中间有重叠就可以接!
debug了好久才发现!是首尾相接!
这么错的恐怕只有我一个了
最近学c++所以用了string
WA2:没有考虑单个单词的情况(数据#4)