跟著別人做也會被誤導的啊,這題做掉的人很快很多,以為排排序之類的就會出來的,後來還拚命的在往簡單的想,導致悲劇無限。
後來亂七八糟搞了下,原來是最簡單的字典樹;
思路:我們簡單的想象一下,把所有要列印的東西構建成一顆字典樹的話,若最後要求的是最後列印過的東西都要刪掉的話,我們要在樹上走的次數是所有的邊都需要走兩次。但現在是最後一次列印之後不需要DELETE,就是說最後一次到達葉子結點時不需要返回到根結點,於是,我們貪心的可以把最長的一條到達葉子的路放在最後(只需要走一次)。
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
string s[10010];
struct NODE
{
NODE *child[26];
//int cnt;
bool flag;
NODE()
{
flag=true;
//cnt=1;
for(int i=0;i<26;i ++)
child[i]=NULL;
}
};
NODE *root;
int ans;
void solve(string str)
{
int len=str.length();
NODE *temp;
temp=root;
int i=0,pos=0,index;
while(i<len)
{
index=str[i]-'a';
if(temp->child[index]!=NULL)
{
temp=temp->child[index];
//temp->cnt++;
}
else
{
temp->child[index]=new NODE();
temp=temp->child[index];
}
i++;
}
}
void finds(string str)
{
NODE *now;
now=root;
int i=0,index,tot=0;
int len=str.length();
while(i<len)
{
index=str[i]-'a';
/*if(now->child[index]->cnt==1)
{
count++;
}*/
if(now->child[index]->flag)
{
tot++;
now->child[index]->flag=false;
}
now=now->child[index];
i ++;
}
ans+=tot*2;
//return count;
}
int main()
{
int i,j,n,len;
string str;
while(cin>>n)
{
int ma=-1,temp;
ans=0;
root=new NODE();
for(i=0;i<n;i++)
{
cin>>s[i];
len=s[i].length();
if(len>ma)
ma=len;
ans++;
solve(s[i]);
}
for(i=0;i<n;i++)
{
finds(s[i]);
//ans+=temp;
//ans-=(s[i].length()-temp);
}
cout<<ans-ma<<endl;
}
return 0;
}