基础的并查集应用,输入可能有一些麻烦,再加上最长公共子串!!!
因为一开始写的最长公共子序列,WA了好多次Σ( ° △ °\|\|\|)︴
#include <iostream> #include <algorithm> #include <string> #include <cstring> using namespace std; int tree[110],len[110],dp[110][110]; double p; string s[110]; void makeSet(int x) { tree[x]=x; } int findSet(int x) { if(x!=tree[x]) tree[x]=findSet(tree[x]); return tree[x]; } void Union(int x,int y) { int fx=findSet(x); int fy=findSet(y); if(fx==fy) return; int mx=0; memset(dp,0,sizeof(dp)); for(int i=1;i<=len[x];i++) { for(int j=1;j<=len[y];j++) { if(s[x][i-1]==s[y][j-1]) { dp[i][j]=dp[i-1][j-1]+1; mx=max(dp[i][j],mx); } else dp[i][j]=0; } } if(mx*100.0/len[x]>p&&mx*100.0/len[y]>p) tree[fx]=fy; } int main(void) { int n,t=0; while(cin>>n>>p) { t++; for(int i=0;i<n;i++) makeSet(i); for(int i=0;i<n;i++) { cin>>s[i]; len[i]=s[i].length(); for(int j=0;j<i;j++) Union(i,j); } int ans=0; for(int i=0;i<n;i++) if(tree[i]==i) ans++; printf("Case %d:\n",t); printf("%d\n",ans); } return 0; }
时间: 2024-10-09 15:44:04