标签:mat ble stack txt 新建 pen cto 统计 problem
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)
标签:mat ble stack txt 新建 pen cto 统计 problem
原文地址:https://www.cnblogs.com/fht-litost/p/9627758.html