7.9 单词游戏 搜索


  7.9 单词游戏

源程序名            words.???(pas, c, cpp)

可执行文件名        words.exe

输入文件名          words.in

输出文件名          words.out

【问题描述】

       Io和Ao在玩一个单词游戏。

       他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致。

    游戏可以从任何一个单词开始。

    任何单词禁止说两遍,游戏中只能使用给定词典中含有的单词。

    游戏的复杂度定义为游戏中所使用的单词长度总和。

    编写程序,求出使用一本给定的词典来玩这个游戏所能达到的游戏最大可能复杂度。

【输入】

       输入文件的第一行,表示一个自然数N(1≤N≤16),N表示一本字典中包含的单词数量以下的每一行包含字典中的一个单词,每一个单词是由字母A、E、I、O和U组成的一个字符串,每个单词的长度将小于等于100,所有的单词是不一样的。

【输出】

       输出文件仅有一行,表示该游戏的最大可能复杂度。

【样例】

       words.in                                            words.out

       5                                                      16

       IOO

       IUUO

       AI

       OIOOI

       AOOI

【问题分析】

       枚举要取的单词,如果这个单词构成的图存在欧拉路(不一定是回路),则存在一个单词接龙的方案,这些单词的长度和就是一个解。答案是所有解的最大值。算法的时间复杂度是O(2n·n),n≤16。

 

PROGRAM words;
CONST
    maxrijeci=100;
    maxdulj=100;
VAR
    n:integer;
    nrijec:ARRAY[1..5, 1..5] OF integer;
    dulj:ARRAY[1..5, 1..5, 1..maxrijeci] OF integer;

FUNCTION num(c:char):integer;
BEGIN
    CASE c OF
        'A':num:=1;
        'E':num:=2;
        'I':num:=3;
        'O':num:=4;
        'U':num:=5;
    END;
END;

PROCEDURE citaj_ulaz;
VAR fin:text;
    i, j, k, l, t:integer;
    tmp:STRING[maxdulj];
    prvi, zadnji:integer;

BEGIN
    FOR i:=1 TO 5 DO
        FOR j:=1 TO 5 DO
            nrijec[i, j]:=0;
    assign(fin, 'WORDS.in');
    reset(fin);
    readln(fin, n);
    FOR i:=1 TO n DO
    BEGIN
        readln(fin, tmp);
        prvi:=num(tmp[1]);
        zadnji:=num(tmp[length(tmp)]);
        inc(nrijec[prvi, zadnji]);
        dulj[prvi, zadnji, nrijec[prvi, zadnji]]:=length(tmp);
    END;
    close(fin);
    { Sortiram rijeci po duljini }
    FOR i:=1 TO 5 DO
        FOR j:=1 TO 5 DO
            FOR k:=1 TO nrijec[i, j]-1 DO
                FOR l:=k+1 TO nrijec[i, j] DO
                    IF dulj[i, j, k]>dulj[i, j, l] THEN
                    BEGIN
                        t:=dulj[i, j, k];
                        dulj[i, j, k]:=dulj[i, j, l];
                        dulj[i, j, l]:=t;
                    END;
END;

FUNCTION nadji (zadnji:integer):integer;
VAR i:integer;
    max:integer;
    tmp:integer;
BEGIN
    max:=0;
    FOR i:=1 TO 5 DO
        IF nrijec[zadnji, i]>0 THEN
        BEGIN
            dec(nrijec[zadnji, i]);
            tmp:=dulj[zadnji, i, nrijec[zadnji, i]+1]+nadji(i);
            inc(nrijec[zadnji, i]);
            IF tmp>max THEN max:=tmp;
        END;
    nadji:=max;
END;

PROCEDURE rijesi;
VAR fout:text;
    i:integer;
    max, tmp:integer;
BEGIN
    max:=0;
    FOR i:=1 TO 5 DO
    BEGIN
        tmp:=nadji(i);
        IF (tmp>max) THEN max:=tmp;
    END;
    assign(fout, 'WORDS.out');
    rewrite(fout);
    writeln(fout, max);
    close(fout);
END;

{ Glavni program }
BEGIN
    citaj_ulaz;
    rijesi;
END.


 

你可能感兴趣的:(搜索,习题,恶心的题目,S!)