您的位置:首页 > 运维架构

SRM 542 DIV2 950 StrangeDictionary

2016-09-13 16:32 399 查看
Task:

给你若干个字符串,然后给它们进行排序,但排序依照的位数是一个随机生成的排列(就是你可能对两个长度为三的字符串,先将它们的第2位进行比较,再比较第1位,再比较第3位才能得到它们的大小关系),那么求出每个字符串的期望排序后的位置,(n<=50)

Solution:

对于两个字符串,我们数出第一个中比第二个大的字符有k1个,第二个中比第一个大的有k2个.那么我们就可以将ans[i]+=1.0∗k1/(k1+k2),ans[j]+=1.0∗k2/(k1+k2).

因为对于这两个字符串,i在j前面的可能性为1.0∗k1/(k1+k2),j在i前面的可能性为1.0∗k2/(k1+k2),那么它们对各自的贡献就是这个了.

以上是题解的方法(根本想不到,想看我的想法的话继续看吧)

vector<double>ans;
class StrangeDictionary {
public:
vector <double> getExpectedPositions(vector <string> words) {
ans.clear();
int sz=words.size(),L
e89b
=words[0].length();
for(int i=0;i<sz;i++)ans.push_back(0);
for(int i=0;i<sz;i++){
string now=words[i];
for(int j=i+1;j<sz;j++){
string nx=words[j];
int les=0,gre=0;
for(int k=0;k<L;k++)
if(now[k]>nx[k])gre++;
else if(now[k]<nx[k])les++;
ans[i]+=1.0*(gre)/(gre+les);
ans[j]+=1.0*(les)/(gre+les);
}
}
return ans;
}
};


我们首先先处理出50的阶乘Base(我用double存),以及C[50][50],然后的操作也是观察两个字符串,并数出其中相同的有多少个(cnt),大的有多少个(gre),小的有多少个(les).

然后再枚举前面放多少个相同的(i),就能够算出此时对答案的贡献->C[cnt][i]∗Base[i]∗Base[L−i−1]∗gre(或les)

最后return答案时除以Base[L]就行了.

vector<double>ans;
double Base[55],C[55][55];
class StrangeDictionary {
public:
vector <double> getExpectedPositions(vector <string> words) {
ans.clear();
int sz=words.size(),L=words[0].length();
for(int i=0;i<sz;i++)ans.push_back(0);
Base[0]=1;
for(int i=1;i<=50;i++)Base[i]=Base[i-1]*i;
for(int i=0;i<=50;i++)C[i][i]=C[i][0]=1;
for(int i=1;i<=50;i++)
for(int j=1;j<i;j++)C[i][j]=C[i-1][j-1]+C[i-1][j];
for(int i=0;i<sz;i++){
string now=words[i];
for(int j=i+1;j<sz;j++){
string nx=words[j];
int cnt=0,les=0,gre=0;
for(int k=0;k<L;k++)
if(now[k]==nx[k])cnt++;
else if(now[k]>nx[k])gre++;
else if(now[k]<nx[k])les++;
for(int k=0;k<=cnt;k++){
ans[i]+=Base[L-k-1]*gre*Base[k]*C[cnt][k];
ans[j]+=Base[L-k-1]*les*Base[k]*C[cnt][k];
}
}
}
for(int i=0;i<sz;i++){
cout<<ans[i]<<endl;
ans[i]/=Base[L];
}
return ans;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  topcoder