题目大意:给定一个字符串,求任意子串中元音字母I, E, A, O, U, Y所占比例之和。
要求 :
思路:咋一看很困难,细细一想就知道怎么作了。因为要求所有子串,所以枚举每个长度,求出当前长度的所有子串的元音字母所占比例,求和即为结果。接下来就是怎么求所有子串中元音字母个数以及所占比例了。因为当子串长度为i时,必然可以有好多个,simple(i)中分母值一定,分子值相加即可,所以我们可以不必考虑每个子串中元音字母的个数,只需要考虑子串长度为i时所有的原因字母数之和num即可。设数组sub[i]表示第i个字符前面的原音字母个数。则子串长度为1时, num1即为sub[l](l为字符串长度) , 子串长度为2 时,num2 = num1 + sub[l - 1] - sub[1] .长度为3 时 ,num3 = num2 + sub[l - 2] - sub[2]……到此处,所有问题都已解决,直接枚举长度即可。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <bitset>
using namespace std;
#define maxn 600000
int sub[maxn];
int main()
{
string str;
while(cin >> str)
{
int len = str.length();
memset(sub , 0 , sizeof(sub));
for(int i = 0 ; i < len ; i ++)
{
if(str[i] == 'A' || str[i] == 'O' ||str[i] == 'E' ||str[i] == 'I' ||str[i] == 'U'||str[i] == 'Y') sub[i + 1] ++ ;
if(i != len - 1) sub[i+2] += sub[i + 1];
}
double ans = 0;
double num = 0;
for(int i = 1 ; i <= len ; i ++)
{
num += (sub[len - i + 1] - sub[i - 1]);
ans += num / i;
}
printf("%.7lf\n" , ans);
}
return 0;
}