uva 11732 "strcmp()" Anyone?
Posted 日拱一卒 功不唐捐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uva 11732 "strcmp()" Anyone?相关的知识,希望对你有一定的参考价值。
https://vjudge.net/problem/UVA-11732
题意:
给出许多字符串,他们两两按下面的函数比较
输出比较次数
s[i]==t[i] , 和 s[i]==\'\\0\' 各算一次比较
法一:
每两个字符串,要么全部匹配,要么中间停止匹配
如果全部匹配,比较次数为 2*len+2(‘\\0’两次匹配)
如果中间停止匹配,比较次数为 2*相同前缀长度+1 (1次失败匹配后退出)
所以
1、对于第i个字符串,先加上i-1,即假设全部 中间停止匹配
这样最后再加上全部匹配数
2、匹配一个就+sum*2
#include<cstdio> #include<cstring> #define N 1001 using namespace std; char s[N]; int sum[N*4001],len,trie[N*4001][63],tot; long long ans; int mark[N*4001]; int get(int i) { if(s[i]>=\'0\'&&s[i]<=\'9\') return s[i]-\'0\'; if(s[i]>=\'a\'&&s[i]<=\'z\') return s[i]-\'a\'+10; if(s[i]>=\'A\'&&s[i]<=\'Z\') return s[i]-\'A\'+36; } void insert(int cnt) { int root=0,id; ans+=cnt; for(int i=0;i<len;i++) { id=get(i); if(!trie[root][id]) { trie[root][id]=++tot; memset(trie[tot],0,sizeof(trie[tot])); sum[tot]=mark[tot]=0; } root=trie[root][id]; ans+=sum[root]<<1; sum[root]++; } ans+=mark[root]; mark[root]++; } int main() { int n,t=0; while(scanf("%d",&n)!=EOF) { if(!n) return 0; memset(trie[0],0,sizeof(trie[0])); ans=0;tot=0; for(int i=1;i<=n;i++) { scanf("%s",s); len=strlen(s); insert(i-1); } printf("Case %d: %lld\\n",++t,ans); } }
法二:
用cnt记录现在还剩下几个是匹配的
那么每次
1、ans+=cnt-sum 匹配失败
2、ans+=sum*2 匹配成功
3、cnt=sum
注意:为了好处理,所以字符串的结束符也算上了
那么这就要循环到len,另外特殊给‘\\0’赋一个id
#include<cstdio> #include<cstring> #define N 1001 using namespace std; char s[N]; int sum[N*4001],len,trie[N*4001][63],tot; long long ans; int get(int i) { if(s[i]>=\'0\'&&s[i]<=\'9\') return s[i]-\'0\'; if(s[i]>=\'a\'&&s[i]<=\'z\') return s[i]-\'a\'+10; if(s[i]>=\'A\'&&s[i]<=\'Z\') return s[i]-\'A\'+36; return 62; } void insert(int cnt) { int root=0,id; for(int i=0;i<=len;i++) { id=get(i); if(!trie[root][id]) { trie[root][id]=++tot; memset(trie[tot],0,sizeof(trie[tot])); sum[tot]=0; } root=trie[root][id]; ans+=cnt-sum[root]; ans+=sum[root]<<1; cnt=sum[root]; sum[root]++; } } int main() { int n,t=0; while(scanf("%d",&n)!=EOF) { if(!n) return 0; memset(trie[0],0,sizeof(trie[0])); ans=0;tot=0; for(int i=1;i<=n;i++) { scanf("%s",s); len=strlen(s); insert(i-1); } printf("Case %d: %lld\\n",++t,ans); } }
以上是关于uva 11732 "strcmp()" Anyone?的主要内容,如果未能解决你的问题,请参考以下文章
UVa 11732 "strcmp()" Anyone? (左儿子右兄弟前缀树Trie)