hdu 3460
算法:字典树
题意:给你一些单词,有一台打印机只能进行以下三种操作
1.读入
2.删除
3.打印
让你输出最少的操作次数将这些单词全部打印出来;
(字典树节点-1)*2 表示读入和删除操作;
打印操作 单词数
最后一个最长的单词不需要进行删除操作;
所以答案=(字典树节点-1)*2+单词数-最长的字符串;
Input
There are several test cases in the input.
Each test case begin with one integer N (1 ≤ N ≤ 10000), indicating the number of team names.
Then N strings follow, each string only contains lowercases, not empty, and its length is no more than 50.
The input terminates by end of file marker.
Output
For each test case, output one integer, indicating minimum number of operations.
Sample Input
2
freeradiant
freeopen
Sample Output
21
代码:
#include<iostream> #include <string> #include <iomanip> #include <cmath> #include <algorithm> #include <cstring> #include <stdio.h> using namespace std; #define Max 30 struct dot { dot *next[Max]; }; dot *newnode() { dot *temp=new dot; for(int i=0;i<Max;i++) temp->next[i]=NULL; return temp; } void tree(char *st,dot *root,int &k) { dot *p=root; int id=0; for(int i=0;i<strlen(st);i++) { id=st[i]-'a'; if(p->next[id]==NULL) { k++; //记录节点数; p->next[id]=newnode(); } p=p->next[id]; } } void del(dot *t) { if(t==NULL) return ; for(int i=0;i<Max;i++) if(t->next[i]==NULL) del(t->next[i]); delete t; } int main() { char st[55]; int n,m,i,j,k; while(cin>>n) { dot *root; root=newnode(); k=0;//没有记录跟节点 m=0; j=n; while(n--) { cin>>st; i=strlen(st); m=max(m,i); tree(st,root,k); } cout<<k*2+j-m<<endl;//没有记录跟节点,所以不需要减一 del(root); } return 0; }
世上无难事,只怕有心人!