codeforces 930b//Game with String// Codeforces Round #468 (Div. 1)

题意:一个串,右循环移位后,告诉你第一个字母,还能告诉你一个,问你能确定移位后的串的概率。

用map记录每个字母出现的位置。对于每个字母,用arr[j][k]记录它的所有出现位置的后j位是字母k的个数。对每个j数arr[j]中arr[j][k]等于1的个数,取最大,说明k取这个时区分该字母的概率最大。统计所有字母的该值除以字符串长度即为结果。

//#pragma comment(linker,"/STACK:1024000000,1024000000") 
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#include <stack>
#include <bitset>
#include <iomanip>
using namespace std;
const int SZ=5010,INF=0x7FFFFFFF;
typedef long long lon;
bool vst[26];
set<int> st[26];
short cnt[SZ][26];

double work(int n,const string &str)
{
    int res=0;
    for(int i=0;i<26;++i)
    {
        if(st[i].size()==0)continue;
        memset(cnt,0,sizeof(cnt));
        for(auto it=st[i].begin();it!=st[i].end();++it)
        {
            int pos=*it;
            for(int j=1;j<n;++j)
            {
                ++cnt[j][str[(pos+j)%n]-'a'];
            }
        }
        int maxv=0;
        for(int j=1;j<n;++j)
        {
            maxv=max(maxv,(int)count(cnt[j],cnt[j]+26,1));
        }
        res+=maxv;
    }
    //cout<<res<<" "<<str.size()<<endl;
    return (double)res/str.size();
}

int main()
{
    std::ios::sync_with_stdio(0);
    //freopen("d:\\1.txt","r",stdin); 
    //for(;scanf("%d",&n)!=EOF;)
    {
        string str;
        cin>>str;
        for(int i=0;i<str.size();++i)
        {
            st[str[i]-'a'].insert(i);
        }
        cout<<fixed<<setprecision(7)<<work(str.size(),str)<<endl;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/gaudar/p/9719429.html