http://acm.hdu.edu.cn/showproblem.php?pid=2978
题意 给出一些串 用yes表示背过了该串,问最难背的子串(子串在yes中/子串在所有字串中的个数 最小)若子串在所有字串中的个数小于m忽略
思路 暴力用map存下所有长度为k的子串及个数,最后遍历判断即可
#include <iostream>
#include <set>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
using namespace std;
const int maxn=10005;
const double eps=1e-9;
map<string,int>M;
struct Node
{
int yes,num;
string ss;
} a[maxn];
int main()
{
int n,m,k;
int flag;
int cas=0;
string s1,s2;
while(scanf("%d",&n)&&n)
{
flag=0;
M.clear();
int tot=0;
scanf("%d%d",&m,&k);
while(n--)
{
cin>>s1>>s2;
map<string,int>M2;
M2.clear();
int len=s1.length();
for(int i=0; i<=len-k; i++)
{
string tmp="";
for(int j=0; j<k; j++)
tmp+=s1[i+j];
if(!M2[tmp])
{
M2[tmp]=1;
int id;
if(M[tmp]==0)
{
M[tmp]=++tot;
id=tot;
a[id].num=0;
a[id].yes=0;
a[id].ss=tmp;
}
else
id=M[tmp];
a[id].num++;
if(s2=="Yes")
a[id].yes++;
}
}
double minn=1e9;
for(int i=1; i<=tot; i++)
{
if(a[i].num>=m)
{
double yes1=(double)a[i].yes,num1=(double)a[i].num;
if(fabs(yes1/num1-minn)<eps)
{
if(a[i].num>a[flag].num)
{
flag=i;
}
else if(a[i].num==a[flag].num)
{
if(a[i].ss<a[flag].ss)
flag=i;
}
}
else if(yes1/num1<minn)
{
minn=(double)yes1/num1;
flag=i;
}
}
}
}
// for(int i=1; i<=tot; i++)
// {
// cout<<a[i].ss<<" "<<a[i].yes<<" "<<a[i].num<<endl;
// }
printf("Case %d: ",++cas);
if(flag==0)cout<<"No solution"<<endl;
else cout<<a[flag].ss<<endl;
}
return 0;
}
/* 5 2 3 EEECEGBFCBFC Yes BFCG No DEBFCEGEEC No CEG No CEG No EEE 1 1 EEC 1 2 ECE 1 1 CEG 1 4 EGB 1 1 GBF 1 1 BFC 1 3 FCB 1 1 CBF 1 1 FCE 0 2 DEB 0 1 EBF 0 1 EGE 0 1 GEE 0 1 BFC */