509E Pretty Song
When Sasha was studying in the seventh grade, he started listening to music a lot. In order to evaluate which songs he likes more, he introduced the notion of the song's prettiness. The title of the song is a word consisting of uppercase Latin letters. The prettiness of the song is the prettiness of its title.
Let's define the simple prettiness of a word as the ratio of the number of vowels in the word to the number of all letters in the word.
Let's define the prettiness of a word as the sum of simple prettiness of all the substrings of the word.
More formally, let's define the function vowel(c) which is equal to 1, if c is a vowel, and to 0 otherwise. Let si be the i-th character of string s, and si..j be the substring of word s, staring at the i-th character and ending at the j-th character (sisi + 1... sj, i ≤ j).
Then the simple prettiness of s is defined by the formula:

The prettiness of s equals

Find the prettiness of the given song title.
We assume that the vowels are I, E, A, O, U, Y.
The input contains a single string s (1 ≤ |s| ≤ 5·105) — the title of the song.
Print the prettiness of the song with the absolute or relative error of at most 10 - 6.
IEAIAIO
28.0000000
BYOB
5.8333333
YISVOWEL
17.0500000
In the first sample all letters are vowels. The simple prettiness of each substring is 1. The word of length 7 has 28 substrings. So, theprettiness of the song equals to 28.
题意:给你一个字符串s,对于每个子串s',simple(s')=元音字符数目/子串长度,最后将各个simple的值相加。
思路:刚开始看到这种数学题很头疼,但细细一推就发现了规律,比如对于EEEEE的字符串,先算对于每个字符的simple分值,对于第一个字符:1+1/2+1/3+1/4+1/5,第二个:1+1/2*2+1/3*2+1/4*2+1/5,第三个:1+1/2*2+1/3*3+1/4*2+1/5,第四个=第二个,第五个=第一个。
对于前一半的字符,数值递增有规律,每次沿两端都少一个1/i,自己可以在取个更长的字符计算找规律验证下。
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
char s[500013];
double harmonic[500013];
int main()
{
scanf("%s",&s);
int len = strlen(s);
harmonic[0] = 0;
for (int i=1; i<=len; i++)
harmonic[i] = harmonic[i-1]+1.0/i;
double ans = 0;
double cur = 0;
for (int i=0; i<len; i++)
{
cur+=harmonic[len-i]-harmonic[i]; //这里在后半段时候会成负数减去多余的值
if (s[i]=='A' || s[i]=='E' || s[i]=='I' || s[i]=='O' || s[i]=='U' || s[i]=='Y')
ans+=cur;
// printf("i=%d,cur=%lf,ans=%lf\n",i,cur,ans);
}
printf("%1.8f\n",ans);
return 0;
}

浙公网安备 33010602011771号