[ZOJ 1387] [POJ 1432] Decoding Morse Sequences

ZOJ: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1387

POJ: http://poj.org/problem?id=1432


題目大意:

給出一個字母的譯碼錶,給出一個有n個單詞的字典,給出一串編碼。問再給出字典中有多少種不同的解碼方式。


題目分析:

首先編碼只有-和.,可以很方便地建立一棵Trie樹,還是最熟悉的二叉方式。

typedef struct trie
{
    int count;                  //單詞數 
    struct trie *dot, *dash;    
}trie;

之後將每一個讀入的單詞插到Trie樹上。

 用動態規劃處理 Morse sequence, 下面記爲str。

記f[i]爲第i個字符到strlen(str)-1的不同解碼數,f[i]=sum(f[i+j]*count[k], 表示從i開始的j位可以解碼爲一個單詞,且相同編碼的單詞有count[k]個),具體的count和單詞的匹配用之前建立的Trie樹完成。


源代碼:

Trie樹的寫法根據看到的一個感覺不錯的版本修改過。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#define maxn 10010
#define maxlen 20010

const char* morse[26] = {
".-",   "-...", "-.-.", "-..",
".",    "..-.", "--.",  "....",
"..",   ".---", "-.-",  ".-..",
"--",   "-.",   "---",  ".--.",
"--.-", ".-.",  "...",  "-",
"..-",  "...-", ".--",  "-..-",
"-.--", "--.."
};			

typedef struct trie
{
    int count;                  //單詞數 
    struct trie *dot, *dash;    
}trie;

trie *trie_new()
{
    trie *t = (trie *)malloc(sizeof(trie));
    t->dot = t->dash = NULL;
    t->count = 0;
    return t;
}

void trie_add(trie *root, const char code[])
{
    int p=0, len=strlen(code);
    trie *node=root;
    while (p<len)
    {
        if (code[p]=='.')
        {
            if (!node->dot)
                node->dot = trie_new();
            node = node->dot;
        }
        else
        {
            if (!node->dash)
                node->dash = trie_new();
            node = node->dash;
        }
        p++;
    }
    node->count++;
}

void trie_free(trie *p)
{
    if (p)
    {
        trie_free(p->dot);
        trie_free(p->dash);
        free(p);
    }
}

void getmorse(const char word[], char code[])
{
    int j=0;
    for (int i=0; i<strlen(word); i++)
    {
        int mlen=strlen(morse[word[i]-'A']); 
        for (int k=0; k<mlen; k++, j++)
            code[j]=morse[word[i]-'A'][k];
    }
    code[j]='\0';
}

void init(char str[], trie *root)
{
    int n;
    char word[maxlen], code[maxlen];
    scanf("%s", str);
    scanf("%d", &n);
    for (int i=0; i<n; i++)
    {
        scanf("%s", word);
        getmorse(word, code);
        trie_add(root, code);
    }
}

int dp(const char str[], trie *root)
{
    int f[maxn];
    int slen=strlen(str);
    f[slen]=1;
    for (int i=slen-1; i>=0; i--)
    {
        f[i]=0;
        trie *p=root;
        for (int j=i; j<slen; j++)
        {
            if (str[j]=='.')
            {
                if (p->dot==NULL) break;
                p=p->dot;
            }
            else
            {
                if (p->dash==NULL) break;
                p=p->dash;
            }
            if (p->count!=0) f[i] += (p->count)*f[j+1];
        }
    }
    return f[0];
}

int main()
{
    char str[maxlen];
    int cs, ans;
    trie *root;
    scanf("%d", &cs);
    while (cs--)
    {
        trie_free(root);
        root = trie_new();
        init(str, root);
        ans = dp(str, root);
        printf("%d\n", ans);
    }
    return 0;
}


題目分析:
題目分析:
題目分析:
題目分析:
發佈了43 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章