题目链接:点击打开链接
题目大意:略。
解题思路:
1、单词筛选(考虑长度)并统一大或小写。
2、set 自带去重统计 + st.size()(用 set 存放且用 set 统计)。
3、注意:一开始存放的时候,直接去重。
4、用 set count 来做最后的统计,否则用其他容器统计完又清空会 TLE。
AC 代码
#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a);
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
set<string> st[110];
int main()
{
int n;
char ts[15],s[100];
while(~scanf("%d",&n))
{
int kase=1;
for(int i=0;i<110;i++) st[i].clear();
while(~scanf("%s",s))
{
int len=strlen(s),k=0;
if(s[0]=='#' && len==1)
{
if(kase++==n) break;
}
for(int i=0;i<len;i++)
{
if(s[i]>='a'&&s[i]<='z') s[i]=toupper(s[i]);
}
for(int i=0,f=0;i<len;i++)
{
char c=s[i];
if(isupper(c))
{
if(f) continue;
ts[k++]=c;
if(k>=10) // 超过10,有字符分隔else会处理,没有字符分隔这边处理
{
ts[k++]='\0';
f=1;
k=0; // 避免与for外面的判断混淆
st[kase].insert(ts);
}
}
else // 有字符分隔
{
if(!f) // 没超过10
{
if(k>=3)
{
ts[k++]='\0';
st[kase].insert(ts);
}
}
else; // 超过10
f=0;
k=0;
}
}
if(k>=3)
{
ts[k++]='\0';
st[kase].insert(ts);
}
}
// for(int i=1;i<=n;i++)
// {
// printf("%d:\n",i);
// for(set<string>::iterator it=st[i].begin();it!=st[i].end();it++)
// {
// printf("%s ",(*it).c_str());
// }
// puts("\n-----------------");
// }
int m,a,b; scanf("%d",&m);
for(int i=0,up;i<m;i++)
{
up=0;
scanf("%d%d",&a,&b);
int mi=min(st[a].size(),st[b].size());
if(st[a].size()==mi)
{
for(set<string>::iterator it=st[a].begin();it!=st[a].end();it++)
if(st[b].count(*it)==1) up++;
}
else
{
for(set<string>::iterator it=st[b].begin();it!=st[b].end();it++)
if(st[a].count(*it)==1) up++;
}
printf("%.1f%%\n",up*1.0/(st[a].size()+st[b].size()-up)*100);
}
}
return 0;
}