题意:一个串,右循环移位后,告诉你第一个字母,还能告诉你一个,问你能确定移位后的串的概率。
用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; }