2 freeradiant freeopen
21HintThe sample's operation is: f-r-e-e-o-p-e-n-Print-Del-Del-Del-Del-r-a-d-i-a-n-t-Print
#include <cstring> #include <vector> #include <cstdio> using namespace std; //*********************************************************************************************** const int maxnode = 10000 * 50 + 10; const int sigma_size = 26; // 字母表为全体小写字母的Trie struct Trie { int ch[maxnode][sigma_size]; int val[maxnode]; int sz; // 结点总数 void clear() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); } // 初始时只有一个根结点 int idx(char c) { return c - 'a'; } // 字符c的编号 // 插入字符串s,附加信息为v。注意v必须非0,因为0代表“本结点不是单词结点” void insert(const char *s, int v) { int u = 0, n = strlen(s); for(int i = 0; i < n; i++) { int c = idx(s[i]); if(!ch[u][c]) { // 结点不存在 memset(ch[sz], 0, sizeof(ch[sz])); val[sz] = 0; // 中间结点的附加信息为0 ch[u][c] = sz++; // 新建结点 } u = ch[u][c]; // 往下走 } val[u] = v; // 字符串的最后一个字符的附加信息为v } }; //***************************************************************************************************** //以下为模板测试 Trie trie; char s[100]; int main() { int n; while(scanf("%d",&n)!=EOF){ trie.clear(); int maxv=0; for(int i=1;i<=n;i++){ scanf("%s",s); int len=strlen(s); maxv=max(maxv,len); trie.insert(s,1); } printf("%d\n",(trie.sz-1)*2-maxv+n); } return 0; } /* 3 abcded abcdehi abcdhijk */
总的单词长度加起来即为sum,构造好字典树之后利用栈进行dfs,如果对于字典树中的结点它的v大于1(证明不止一个单词经过这个结点),答案减去(v-1)*2,最后再减去最长单词的长度(因为最后一个单词肯定只需要访问一次)+n
#include <cstring> #include <vector> #include <cstdio> #include<stack> using namespace std; const int maxnode = 10000 * 50 + 10; const int sigma_size = 26; char s[110],s1[110]; stack<int>st; // 字母表为全体小写字母的Trie struct Trie { int ch[maxnode][sigma_size]; int val[maxnode]; int sz; // 结点总数 void clear() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); } // 初始时只有一个根结点 int idx(char c) { return c - 'a'; } // 字符c的编号 void insert(const char *s, int v) { int u = 0, n = strlen(s); for(int i = 0; i < n; i++) { int c = idx(s[i]); if(!ch[u][c]) { // 结点不存在 memset(ch[sz], 0, sizeof(ch[sz])); val[sz]=0; ch[u][c] = sz++; // 新建结点 } u = ch[u][c]; // 往下走 val[u]+=v; } } int dfs(int v){ int sum=0; while(!st.empty()) st.pop(); st.push(v); while(!st.empty()){ int u=st.top(); st.pop(); if(u!=0) sum+=2*(val[u]-1); for(int i=0;i<26;i++){ if(ch[u][i]!=0) st.push(ch[u][i]); } } return sum; } }; Trie trie; int main() { int n; while(scanf("%d",&n)!=EOF){ trie.clear(); int maxv=0,sum=0; for(int i=1;i<=n;i++){ scanf("%s",s); int len=strlen(s); sum+=len; maxv=max(maxv,len); trie.insert(s,1); } printf("%d\n",sum*2-trie.dfs(0)-maxv+n); } return 0; }