这题其实就是后缀相同的对数,我们可以倒序插入到Trie树中,之后贪心的选前缀长的,之后再选前缀小的,这样比较好用dfs操作
#include<iostream> #include<cstring> #include<cstdio> #include<map> #include<algorithm> #include<queue> #include<set> #define ull unsigned long long using namespace std; typedef long long ll; typedef pair<int,int> pll; typedef pair<int,pair<int,int> > plll; const int N=1e5+10; const int inf=0x3f3f3f3f; string s; int idx; int tr[N][27]; int cnt[N]; void insert(){ int i; int cur=0; for(i=s.size()-1;i>=0;i--){ int x=s[i]-'A'; if(tr[cur][x]==0) tr[cur][x]=++idx; cur=tr[cur][x]; cnt[cur]++; } } int solve(int u){ if(cnt[u]==1) return 0; int res=0; int i; for(i=0;i<26;i++){ if(tr[u][i]){ res+=solve(tr[u][i]); } } int tmp=cnt[u]-res; if(tmp>=2) res+=2; return res; } int main(){ int t; cin>>t; int times=1; while(t--){ int n; cin>>n; int i; idx=0; memset(tr,0,sizeof tr); memset(cnt,0,sizeof cnt); for(i=1;i<=n;i++){ cin>>s; insert(); } int res=solve(0); printf("Case #%d: ",times++); cout<<res<<endl; } }