样例
样例输入
0.109375
0.000000
0.062500
0.015625
0.109375
0.015625
0.015625
0.000000
0.062500
0.015625
0.000000
0.078125
0.062500
0.062500
0.093750
0.015625
0.015625
0.031250
0.046875
0.046875
0.046875
0.000000
0.000000
0.000000
0.093750
0.000000
L dp Ol Bxtldq, ru brx fdq fdoo ph VsdfhIobhu.
L dp jodg wr vhh brx.
Hqmrb pb frqwhvw.
样例输出
I am Li Yuqian, or you can call me SpaceFlyer.
I am glad to see you.
Enjoy my contest.
目前认为是求k有问题,然鹅并不知道哪里错了,求助
double p[30];//概率
int cnt[30];//桶,记录字母出现次数(下标0~25)
char s[1000100];
bool space[1000100];//空格位置
bool endline[1000100];//换行位置
int main()
{
//freopen("decode.in","r",stdin);
//freopen("decode.out","w",stdout);
for (re int i=0;i<26;++i)
{
scanf("%lf",&p[i]);
}
int end=1;//长度+1(下次读入的开始)
while(scanf("%s",s+end)!=EOF)
{
//gets(s+end);
end=strlen(s+1);
space[end]=1;//记录空格
char c=getchar();
if (c=='\n')
{
endline[end]=1;//记录换行
}
++end;
}
int allcnt=0;//字母个数
for (re int i=1;i<end;++i)
{
if (s[i]>='A'&&s[i]<='Z')
{
++cnt[s[i]-'A'];
++allcnt;
}
else if (s[i]>='a'&&s[i]<='z')
{
++cnt[s[i]-'a'];
++allcnt;
}
}
double best=233333333;//最小方差
int ans=0;
for (re int k=0;k<=25;++k)
{
double now=0;//现在的方差
for (re int i=0;i<26;++i)
{
now+=pow(p[i]-((double)cnt[(i-k+26)%26]/allcnt),2);//还原,所以要减去k
}
if (now<best)
{
best=now;
ans=k;
}
}
int k=ans;
//输出
for (re int i=1;i<end;++i)
{
{
if ((s[i]>='A'&&s[i]<='Z') )
{
if ((s[i]-k>='A'&&s[i]-k<='Z'))
{
putchar(s[i]-k);
}
else
{
putchar(s[i]-k+26);
}
}
else if ((s[i]>='a'&&s[i]<='z') )
{
if ((s[i]-k>='a'&&s[i]-k<='z'))
{
putchar(s[i]-k);
}
else
{
putchar(s[i]-k+26);
}
}
else
{
putchar(s[i]);
}
}
if (space[i]==1&&endline[i]==0)//空格不换行
{
cout<<' ';
}
else if (endline[i]==1)//换行
{
cout<<'\n';
}
}
fclose(stdin);
fclose(stdout);
return 0;
}