我这个英语学渣又把题给翻译错了……(话说,六级差十分没有过,好心疼T T),题目中说的P和Q都是计算game的个数,我以为是出现的次数,各种wa。。后来调整了以后又是各种wa,原来是double型的数据在排序的时候需要注意一下,我们需要给定一个精度,按照一定的规则来进行排序,比如当两个 rate < eps 的时候,我们判断分母的大小,让分母大或者分子小的优先排序,这样就能尽可能地避免精度问题。
总之,题目不难,暴力枚举就可以,但是想一次AC还是挺难的。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cmath> #include<map> using namespace std; #define N 20010 #define eps 1e-7 map<string,int> vis; struct OUT { string mel; int p,q; double rate; }out[N]; void Find_pq(int &p,int &q,string *str,int *suc,int n,int k,string aim) { int lens; string tmp; for(int i = 0; i < n; i++) { lens = str[i].length(); for(int j = 0; j < lens; j++) { if(k+j > lens) break; tmp = ""; for(int u = 0; u < k; u++) { tmp += str[i][j+u]; } if(tmp == aim) { p++; if(suc[i]) q++; break; } } } } bool cmp(OUT o1,OUT o2){ if(fabs(o1.rate-o2.rate) < eps){ if(o1.p != o2.p) return o1.p > o2.p; else return o1.mel < o2.mel; } else return o1.rate < o2.rate; } string Slove(int cnt){ if(cnt==0) return "No solution"; sort(out,out+cnt,cmp); return out[0].mel; } int main() { int ca=0,lens,m,k,n,cnt,suc[110]; string str[110],jud,ans,tmp; while(cin>>n && n) { cin>>m>>k; cnt = 0; for(int i = 0; i < n; i++) { cin>>str[i]>>jud; if(jud == "Yes") suc[i] = 1; else suc[i] = 0; } vis.clear(); for(int i = 0; i < n; i++) { lens = str[i].length(); for(int j = 0; j < lens; j++) { if(k+j > lens) break; tmp = ""; for(int u = 0; u < k; u++) { tmp += str[i][j+u]; } if(vis[tmp]) continue; vis[tmp] = 1; int p1,q1; int &p = p1,&q = q1; p = q = 0; Find_pq(p,q,str,suc,n,k,tmp);///引用大法好 // cout<<tmp<<" "<<p1<<" "<<q1<<endl; if(p < m) continue; out[cnt].p = p1; out[cnt].q = q1; out[cnt].mel = tmp; out[cnt].rate = q1*1.0 / p1; cnt++; } } ans = Slove(cnt); cout<<"Case "<<++ca<<": "<<ans<<endl; } return 0; }