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
*/