数学规律题,很容易计算的。以初始测试数据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\n", ans); 60 61 62 #ifndef ONLINE_JUDGE 63 printf("%d\n", (int)clock()); 64 #endif 65 66 return 0; 67 }
时间: 2024-10-23 12:11:53