"Strcmp()" Anyone? UVA - 11732
程序员文章站
2022-04-17 14:46:05
...
自己不会写,借用别人的题解,详情点击:题解 , 原题解没有具体的解释,我想强行解释一波。
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
const int maxn=4000001;
int sz;
int trie[maxn][62],time[maxn],isEnd[maxn];//time[i]=k表示第i个结点经过了k个单词,isEnd[j]=k表示以第j个结点结束的单词有k个
long long ans;
int getId(char c)
{
if(c>='0'&&c<='9')return c-'0';
else if(c>='A'&&c<='Z')return c-55;
else return c-61;
}
void insert(char temp[])
{
int u=0,id;
for(int i=0;temp[i];i++)
{
id=getId(temp[i]);
if(!trie[u][id])
{
memset(trie[sz],0,sizeof(trie[sz]));
trie[u][id]=sz++;
ans+=time[u]*(2*i+1);//这种情况是u结点下有多个子结点,设此时有n个子结点,当出现新的子结点时,
//新的子结点需要与其它n个结点比较,总的比较次数为n*(2*i+1),i为新结点在temp串的位置。
}
else ans+=(time[u]-time[trie[u][id]])*(2*i+1);//因为一个父结点有许多子结点,所以会出现父子结点出现次数不一致的现象,父结
//出现的次数减去子结点出现的次数(经过父结点出去temp串的串的个数)乘以子结点在temp串的位置就是比较次数。
time[u]++;
u=trie[u][id];
}
int l=strlen(temp);
ans+=isEnd[u]*2*(l+1);//出现相同的单词需要比较的次数
ans+=(time[u]-isEnd[u])*(2*l+1);//一个单词包含在另一个单词里面需要比较的次数。
time[u]++;
isEnd[u]++;
}
int main()
{
int n;
int cas=1;
while(scanf("%d",&n)&&n)
{
memset(time,0,sizeof(time));
memset(isEnd,0,sizeof(isEnd));
char temp[1000];
memset(trie[0],0,sizeof(trie[0]));
sz=1;
ans=0;
for(int i=0;i<n;i++)
{
scanf("%s",temp);
insert(temp);
}
printf("Case %d: %lld\n",cas++,ans);
}
}
上一篇: 美女妹子笑的心惊胆战的
推荐阅读
-
UVA 11732 strcmp() Anyone? strcmp()函数(Trie)
-
字典树("strcmp()" Anyone? uva11732)
-
"Strcmp()" Anyone? UVA - 11732
-
UVA11732 "strcmp()" Anyone?
-
UVA11732 "strcmp()" Anyone?
-
UVa 11732-strcmp() Anyone?
-
Trie UVA 11732 "strcmp()" Anyone?
-
【uva11732】"strcmp()" Anyone?
-
UVA11732 “strcmp()“ Anyone?
-
UVa 11732 strcmp() Anyone?