题意:给n个字符串,让他们两两比较,求比较的次数。如strcmp("than","that"),strcmp("there","the")各需要7次比较。
思路:简单的模拟肯定不行,所以建立字典树。val数组代表经过该节点的单词书。添加一个isEnd数组来处理两个单词相同时的情况。
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; const int maxnode = 4000010; typedef long long ll; char str[4001]; int val[maxnode]; int ch[maxnode][62]; int isEnd[maxnode]; struct Trie { int sz; ll ans; Trie() { sz = 1; memset(ch,0,sizeof(ch)); memset(val,0,sizeof(val)); memset(isEnd,0,sizeof(isEnd)); ans = 0; } int idx(char s) { if(s>='0'&&s<='9') return s-'0'; else if(s>='A'&&s<='Z') return 10+s-'A'; else return 36+s-'a'; } void insert(char *s) { int u = 0,n = strlen(s); for(int i = 0; i < n; i++) { int v = idx(s[i]); if(ch[u][v]==0) { ans += val[u]*(2*i+1); ch[u][v] = sz++; } else { ans += (val[u]-val[ch[u][v]])*(2*i+1); } val[u]++; u = ch[u][v]; } ans += (isEnd[u]*2*(n+1)); ans += (val[u]-isEnd[u])*(2*n+1); val[u]++; isEnd[u]++; } }; int main() { int n; int kase = 0; while(cin>>n&&n) { Trie trie; for(int i = 0; i < n; i++) { cin >> str; trie.insert(str); } cout<<"Case "<<++kase<<": "<<trie.ans<<endl; } return 0; }