转化与组合
对于一个只含有'a','b'字母的字符串s1,合并相邻且相同的字符之后如果得到的字符串s2为“回文串”,则称s1为“好串”。
回文串:对于长度为len的字符串s[0..len - 1],任意0≤i≤len都有 s[i] = s[len - i - 1],则s为回文串。
例如aaabba合并后为aba,aba为回文串,则原串aabba为“好串”。
现给定字符串s,求s包含多少个长度为偶数“好串”,多少个长度为奇数的“好串”。(好串在s中应为连续的一段子串) s的长度len范围(1<= len <= 100000);
输出ev_ans(偶数好串的个数) od_ans(奇数好串的个数);
思路解析:通过观察任意的相同的字符之间都是一个回文串。由于len最大值为100000,只能用O(n)级复杂度的算法,所以在读到第i位时要判断出第i位时ev_ans和od_ans的值;这样才能在复杂度允许下得出答案;首先我们要判断第i位为奇数位还是偶数位;然后通读读取到第i位,且与之相同字符在奇数位个数,与偶数位的个数来更新答案。
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 5 const int MaxN = 1e5; 6 char s[MaxN + 5]; 7 int len; 8 long long od_a, od_b, od_ans, ev_a, ev_b, ev_ans; 9 10 int main() 11 { 12 scanf("%s", s); 13 len = strlen(s); 14 for(int i = 0; i <= len - 1; i++) 15 { 16 if(i & 1) 17 { 18 if(s[i] == 'a') 19 { 20 od_a++; 21 od_ans += od_a; //如果i为奇数;则od_ans需增加od_a的个数; 22 ev_ans += ev_a; //如果i为奇数;则ev_ans需增加ev_a的个数; 23 } 24 if(s[i] == 'b') 25 { 26 od_b++; 27 od_ans += od_b; 28 ev_ans += ev_b; 29 } 30 } 31 else 32 { 33 if(s[i] == 'a') 34 { 35 ev_a++; 36 od_ans += ev_a; //如果i为偶数;则od_ans需增加ev_a的个数; 37 ev_ans += od_a; //如果i为偶数;则ev_ans需增加od_a的个数; 38 } 39 if(s[i] == 'b') 40 { 41 ev_b++; 42 od_ans += ev_b; 43 ev_ans += od_b; 44 } 45 } 46 } 47 printf("%I64d %I64d\n", ev_ans, od_ans); 48 }
本题重点在于读过1次的字符不能再次搜索,在每一位都更新答案,并记录到本位与本位字符相同的奇数位字符次数,和偶数位次数。

浙公网安备 33010602011771号