NYOJ99 单词拼接

来源:互联网 发布:按层次遍历二叉树算法 编辑:程序博客网 时间:2024/06/11 07:56

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=99

题目分析:
其实上这道题把给的单词转化成一个图,然后考察这个图是否具有一个欧拉回路。
一个图具有欧拉回路的充要条件是这个图是连通的,并且只有0或2个奇点。出度比入度大一的作为起点,出度比入度小一的作为终点。
一开始我把题目抽象错了,试图去把每个单词看成一个节点,然后抽象成图,这种做法是不对的,然而这种不对的想法纠结了我很久,以致于我一直坚持WA的提交。伤心啊。正确的应该是把字符抽象出来,单独的一个字符作为一个节点,来考虑出度和入度。如果一个字符出现在字符串首,那它的出度就+1,该字符通过这个字符串可以到达字符串尾的那个字符;如果出现在字符串尾,入度加1,字符串首的字符可通过该字符串达到该字符。想了好久才想明白。
为什么要用递归,这样节省空间,并且这里的话,递归的效率挺好的。

#include<stdio.h>#include<string.h>#include<stdlib.h>char str[1000][31];bool used[1000];int In[26];int Out[26];int s[1000];//在Judge中用来存放每个字符串的大小Sizeint stack[1000];int n;int compare(const void *a, const void *b){char *p1 = (char *)a;char *p2 = (char *)b;return strcmp(p1, p2);}int Judge(){int i;int last = -1;int first = -1;for(i = 0; i < 26; ++i){if(In[i] != Out[i]){//Out为在串首出现的次数,In为串尾出现的次数if(Out[i] - In[i] == 1 && first == -1)first = i;else if(Out[i] - In[i] == -1 && last == -1)last = i;elsereturn -1;}}if(first > -1 && last > -1)return first;else if(first == -1 && last == -1){for(i = 0; i < 26; ++i)if(In[i] != 0)return i;}elsereturn -1;}bool DFS(char first, int Index)//有可能有多个连通区域{if(Index == n)return true;int i;int b,e,m;b = 0;e = n - 1;while(b <= e)//二分法查找这个首字符,排序好的,肯定快啊。速度绝对比别人快2倍{m = (b + e)/2;if(str[m][0] == first)break;else if(str[m][0] > first)e = m - 1;elseb = m + 1;}if(b > e)return false;//找到这个字符第一次出现的字符串while(str[m][0] == first && m >= 0)--m;for(i = m + 1; str[i][0] == first; ++i){if(!used[i]){stack[Index] = i;used[i] = true;if(DFS(str[i][s[i] - 1], Index + 1))return true;used[i] = false;}}return false;}int main(){int t;int i,first;scanf("%d", &t);while(t--){scanf("%d", &n);for(i = 0; i < n; ++i)scanf("%s", str[i]);memset(used, 0, sizeof(used));memset(In, 0, sizeof(In));memset(Out, 0, sizeof(Out));qsort(str, n, 31 * sizeof(char), compare);for(i = 0; i < n; ++i){s[i] = strlen(str[i]);++Out[str[i][0] - 'a'];++In[str[i][s[i] - 1] - 'a'];}first = Judge();if(first != -1 && DFS(first + 'a', 0)){for(i = 0; i < n - 1; ++i)printf("%s.", str[stack[i]]);printf("%s\n", str[stack[n - 1]]);}elseprintf("***\n");}}