UVaOJ 10129 - Play on Words

来源:互联网 发布:教学电子黑板软件 编辑:程序博客网 时间:2024/06/06 00:59

——by A Code Rabbit


Description

输入一些单词,要求把这些所有的单词都用成语接龙的办法连起来。
输出可能或者不可能。


Types

Date Structure :: Graphs


Analysis

对于每个单词,有价值的就是第一个单词和最后一个单词。

虽然输入数据可能高达100000个,但是字母只有26个。

可以以这些字母为点,把这题的模型化为有向图。

然后题目所求的就是这无向图的一个欧拉路径。

要求欧拉路径,可以计算每个点的入度和出度,容易理解除了第一个单词开头的字母,和最后一个单词结尾的字母,其他的字母入度和出度必然相等。

而第一个单词开头的字母和最后一个单词结尾的字母,前者入度比出度大一,后者出度比入度小一。

不过要记得,当所有点的入度和出度都相等,即构成欧拉回路,也符合题目的要求。

最后别忘了这个定理成立的条件——这个图的无向图,必须是连通的。

DFS 一下某个点的连同分支是否可以到达每个点即可。


Solution

// UVaOJ 10129// Play on Words// by A Code Rabbit#include <cstdio>#include <cstring>const int LIMITS = 2000;int t;char word[LIMITS];int n;bool graph[30][30];bool is_existing[30];int difference[30]; // It means the in_order minus the out_order.bool is_visited[30];void Process(char* word);bool MatchCondition();int Search(int pos);int main() {    scanf("%d", &t);    while (t--) {        // INIT.        memset(difference, 0, sizeof(difference));        memset(graph, false, sizeof(graph));        memset(is_existing, false, sizeof(is_existing));        memset(is_visited, false, sizeof(is_visited));        // Inputs and count.        scanf("%d", &n);        getchar();        while (n--) {            gets(word);            // Processing string.            Process(word);        }        // Compete the number of letters.        int num_letters = 0;        for (int i = 0; i < 26; ++i) {            if (is_existing[i]) {                ++num_letters;            }        }        // Judge whether in_order and out_order match condition.        bool can_order = MatchCondition();           // Judge whether the graph without direction is a connected graph.        if (can_order) {            for (int i = 0; i < 26; ++i) {                if (is_existing[i]) {                    if (num_letters != Search(i)) {                        can_order = false;                    }                    break;                }            }        }        // Outputs.        printf("%s\n", can_order ? "Ordering is possible." : "The door cannot be opened.");    }    return 0;}void Process(char *word) {    int first = word[0] - 'a';    int last = word[strlen(word) - 1] - 'a';    ++difference[first];    --difference[last];    graph[first][last] = true;    graph[last][first] = true;    is_existing[first] = true;    is_existing[last] = true;}bool MatchCondition() {    int num_nonzero = 0;    int num[26];    for (int i = 0; i < 26; ++i) {        if (difference[i]) {            num[num_nonzero++] = difference[i];        }    }    if (num_nonzero == 0) {        return true;    }    if (num_nonzero != 2) {        return false;    }    if ((num[0] == -1 && num[1] ==  1) ||         (num[0] ==  1 && num[1] == -1))    {        return true;    } else {        return false;    }}int Search(int pos) {    if (is_visited[pos]) {        return 0;    }    is_visited[pos] = true;    int sum = 1;    for (int i = 0; i < 26; ++i) {        if (graph[pos][i]) {            sum += Search(i);        }    }    return sum;}


下载PDF

参考资料:无

原创粉丝点击