【CF】509E Pretty Song

数学规律题,很容易计算的。以初始测试数据3为例。
Str    Y I S V O W E L
--------------------------
Len    1  2 3 4  | 5 6 7  8
Y       +           |           +
I        + +        |       + +
S        
V
O       + + + + | + + + +
W
E       +           |           +
L
首先注意1-4与5-8是对称的(仅长度不同)。长度为2的总数可以在长度为1的总数的基础上累加计算(因为2-len-1的字符若为Vow则各递增1),长度为3的可以在长度为2的基础上累加计算。
故,首先求得cnt[]数组表示从1开始到位置n的Vow字符数目。然后遍历1-len/2的长度,求得结果,若len为奇数,则单独再计算一次(len+1)/2。
其实就是递推规律题目,O(n)时间复杂度。

 1 /* 509E */
 2 #include <iostream>
 3 #include <string>
 4 #include <map>
 5 #include <queue>
 6 #include <set>
 7 #include <stack>
 8 #include <vector>
 9 #include <algorithm>
10 #include <cstdio>
11 #include <cmath>
12 #include <ctime>
13 #include <cstring>
14 #include <climits>
15 #include <cctype>
16 using namespace std;
17 
18 #define isVow(ch) (ch=='I'||ch=='E'||ch=='A'||ch=='O'||ch=='U'||ch=='Y')
19 
20 const int maxn = 5e5+5;
21 char s[maxn];
22 int cnt[maxn];
23 
24 int main() {
25     int i, j, k;
26     int len;
27     __int64 sum;
28     int l, r, tmp;
29     double ans;
30     
31     #ifndef ONLINE_JUDGE
32         freopen("data.in", "r", stdin);
33         freopen("data.out", "w", stdout);
34     #endif
35     
36     scanf("%s", s+1);
37     memset(cnt, 0, sizeof(cnt));
38     for (i=1; s[i]; ++i) {
39         if (isVow(s[i]))
40             cnt[i] = cnt[i-1]+1;
41         else
42             cnt[i] = cnt[i-1];
43     }
44     len = i-1;
45     ans = 0.;
46     sum = 0;
47     l = 0;
48     r = len;
49     for (i=1, j=len; i<=len/2; ++i, --j) {
50         sum += cnt[r] - cnt[l];
51         ans += 1.0*sum/i + 1.0*sum/j;
52         ++l;
53         --r;
54     }
55     if (len & 1) {
56         sum += cnt[r] - cnt[l];
57         ans += 1.0*sum/i;
58     }
59     printf("%.7lf
", ans);
60     
61     
62     #ifndef ONLINE_JUDGE
63         printf("%d
", (int)clock());
64     #endif
65     
66     return 0;
67 }
原文地址:https://www.cnblogs.com/bombe1013/p/4435878.html