1. 程式人生 > >UVA - 11732 "strcmp()" Anyone? (trie)

UVA - 11732 "strcmp()" Anyone? (trie)

就是 false 計數 pan size int name 總數 lan

https://vjudge.net/problem/UVA-11732

題意

給定n個字符串,問用strcmp函數比較這些字符串共用多少次比較。

strcmp函數的實現

int strcmp(char *s, char *t)
{
    int i;
    for (i=0; s[i]==t[i]; i++)
        if (s[i]==\0)
            return 0;
    return s[i] - t[i];
}

分析

建trie樹,把‘\0’也加進去,記錄以每個節點為子樹包含的單詞節點。

然後dfs計數,遇到單詞節點,說明可能存在相同的字符串,於是此時ans+=tot[u]*(tot[u]-1)*dep;

否則就是(2*dep+1)*sum,sum為所有選法。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include 
<stack> #include <set> #include <bitset> using namespace std; typedef long long ll; typedef unsigned long long ull; #define ms(a, b) memset(a, b, sizeof(a)) #define pb push_back #define mp make_pair #define pii pair<int, int> //#define eps 0.0000000001 #define IOS ios::sync_with_stdio(0);cin.tie(0); #define
random(a, b) rand()*rand()%(b-a+1)+a #define pi acos(-1) //const ll INF = 0x3f3f3f3f3f3f3f3fll; const int inf = 0x3f3f3f3f; const int maxn = 4000 * 1000 + 10; const int maxm = 4e5 +10; const int mod = 20071027; const int sigma_size = 26; struct Trie{ int head[maxn];// head[i]為第i個結點的左兒子編號 int nxt[maxn];// next[i]為第i個結點的右兄弟編號 char ch[maxn];// ch[i]為第i個結點上的字符 int tot[maxn];// tot[i]為第i個結點為根的子樹包含的葉結點總數 int sz; ll ans;// 答案 void init(){ sz=1; tot[0]=head[0]=nxt[0]=0; } // 插入字符串s(包括最後的‘\0‘),沿途更新tot void insert(char* s){ int u=0,v,n=strlen(s); tot[0]++; for(int i=0;i<=n;i++){ // 找字符a[i] bool f=false; for(v=head[u];v;v=nxt[v]){ if(ch[v]==s[i]){// 找到了 f=true; break; } } if(!f){ v=sz++;// 新建結點 tot[v]=0; ch[v]=s[i]; nxt[v]=head[u]; head[u]=v;// 插入到鏈表的首部 head[v]=0; } u = v; tot[u]++; } } // 統計LCP=u的所有單詞兩兩的比較次數之和 void dfs(int dep,int u){ // 葉結點 if(head[u]==0) ans+=tot[u]*(tot[u]-1)*dep; else{ int sum=0; for(int v=head[u];v;v=nxt[v]){ sum+=tot[v]*(tot[u]-tot[v]); // 子樹v中選一個串,其他子樹中再選一個 } // 除以2是每種選法統計了兩次 ans+=sum/2*(2*dep+1); for(int v=head[u];v;v=nxt[v]) dfs(dep+1,v); } } ll cal(){ ans=0; dfs(0,0); return ans; } }; Trie trie; char tmp[1010]; int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("input.txt", "w", stdout); #endif int cas=1; int T; while(~scanf("%d",&T)&&T){ trie.init(); for(int i=0;i<T;i++){ scanf("%s",tmp); trie.insert(tmp); } printf("Case %d: %lld\n",cas++,trie.cal()); } return 0; }

UVA - 11732 "strcmp()" Anyone? (trie)