UVa 11732 "strcmp()" Anyone? (左兒子右兄弟首碼樹Trie)

來源:互聯網
上載者:User

標籤:

題意:給定strcmp函數,輸入n個字串,讓你用給定的strcmp函數判斷字元比較了多少次。

析:題意不理解的可以閱讀原題https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2832

字串很多,又很長,如果按照題目的意思兩兩比較,肯定會TLE,所以要用首碼樹(Trie)來解決,當然只是用簡單的首碼樹也會TLE的,

我們必須對其進行最佳化,看了網上大牛們的,知道要用左兒子右兄弟的方法來最佳化,說實話,以前還沒用過,看了好久才明白是什麼個意思,

不是很明白的畫個圖想一想就會明白的,我採用的是邊插入邊計算的方法,在每一個分枝都進行計算,然後加和,我們要找每個分枝,

除了最後一個都是2*i+1,最後一個再加上2*i+2。

代碼如下:

#include <cstdio>#include <iostream>#include <cstring>using namespace std;typedef long long LL;const int maxn = 4000 * 1000 + 10;LL ans = 0;char s[1010];struct Trie{    int lson[maxn];    int rbro[maxn];    int val[maxn];    char ch[maxn];    int sz;    void clear(){  sz = 1; lson[0] = rbro[0] = val[0] = 0;  ans = 0; }    void insert(const char *s){        int u = 0, v, n = strlen(s);        for(int i = 0; i <= n; ++i){            for(v = lson[u]; v; v = rbro[v])                if(s[i] == ch[v])  break;//找到結點            if(!v){//建立結點                v = sz++;                ch[v] = s[i];                lson[v] = 0;//左兒子為空白                rbro[v] = lson[u];//結點放在首部                val[v] = 0;//初始化                lson[u] = v;//插入結點            }            ans += (val[u]-val[v]) * (2 * i + 1);//(val[u]-val[v])意思是和v不一樣的單詞數            if(i == n){                ans += val[v] * (2 * i + 2);                ++val[v];            }            ++val[u];  u = v;        }    }};Trie trie;int main(){    int n, kase = 0;    while(scanf("%d", &n), n){        trie.clear();        for(int i = 0; i < n; ++i){            scanf("%s", s);            trie.insert(s);        }        printf("Case %d: %lld\n", ++kase, ans);    }    return 0;}

下面是大牛Rujia Liu的代碼,我基本是根據他的代碼寫的(因為自己確實是寫不出來。。。)

 

// UVa11732 strcmp() Anyone?// Rujia Liu#include<cstring>#include<vector>using namespace std;const int maxnode = 4000 * 1000 + 10;const int sigma_size = 26;// 字母表為全體小寫字母的Triestruct Trie {  int head[maxnode]; // head[i]為第i個結點的左兒子編號  int next[maxnode]; // next[i]為第i個結點的右兄弟編號  char ch[maxnode];  // ch[i]為第i個結點上的字元  int tot[maxnode];  // tot[i]為第i個結點為根的子樹包含的葉結點總數  int sz; // 結點總數  long long ans; // 答案  void clear() { sz = 1; tot[0] = head[0] = next[0] = 0; } // 初始時只有一個根結點  // 插入字串s(包括最後的‘\0‘),沿途更新tot  void insert(const char *s) {    int u = 0, v, n = strlen(s);    tot[0]++;    for(int i = 0; i <= n; i++) {      // 找字元a[i]      bool found = false;      for(v = head[u]; v != 0; v = next[v])        if(ch[v] == s[i]) { // 找到了          found = true;          break;        }      if(!found) {        v = sz++; // 建立結點        tot[v] = 0;        ch[v] = s[i];        next[v] = head[u];        head[u] = v; // 插入到鏈表的首部        head[v] = 0;      }      u = v;      tot[u]++;    }  }  // 統計LCP=u的所有單詞兩兩的比較次數之和  void dfs(int depth, int u) {    if(head[u] == 0) // 葉結點      ans += tot[u] * (tot[u] - 1) * depth;    else {      int sum = 0;      for(int v = head[u]; v != 0; v = next[v])        sum += tot[v] * (tot[u] - tot[v]); // 子樹v中選一個串,其他子樹中再選一個      ans += sum / 2 * (2 * depth + 1); // 除以2是每種選法統計了兩次      for(int v = head[u]; v != 0; v = next[v])        dfs(depth+1, v);    }  }  // 統計  long long count() {    ans = 0;    dfs(0, 0);    return ans;  }};#include<cstdio>const int maxl = 1000 + 10;   // 每個單詞最大長度int n;char word[maxl];Trie trie;int main() {  int kase = 1;  while(scanf("%d", &n) == 1 && n) {    trie.clear();    for(int i = 0; i < n; i++) {      scanf("%s", word);      trie.insert(word);    }    printf("Case %d: %lld\n", kase++, trie.count());  }  return 0;}

 

UVa 11732 "strcmp()" Anyone? (左兒子右兄弟首碼樹Trie)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.