首页 > 其他 > 详细

转化与组合

时间:2015-11-24 20:18:26      阅读:293      评论:0      收藏:0      [点我收藏+]
对于一个只含有‘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位,且与之相同字符在奇数位个数,与偶数位的个数来更新答案。

#include <cstdio>
#include <cstring>
using namespace std;

const int MaxN = 1e5;
char s[MaxN + 5];
int len;
long long od_a, od_b, od_ans, ev_a, ev_b, ev_ans;

int main()
{
  scanf("%s", s);
  len = strlen(s);
  for(int i = 0; i <= len - 1; i++)
  {
    if(i & 1)
    {
      if(s[i] == ‘a‘)
      {
        od_a++;    
        od_ans += od_a;   //如果i为奇数;则od_ans需增加od_a的个数;
        ev_ans += ev_a;   //如果i为奇数;则ev_ans需增加ev_a的个数;
      }
      if(s[i] == ‘b‘)
      {
        od_b++;
        od_ans += od_b;   
        ev_ans += ev_b;  
      }
    }
    else
    {
      if(s[i] == ‘a‘)
      {
        ev_a++;
        od_ans += ev_a;   //如果i为偶数;则od_ans需增加ev_a的个数;
        ev_ans += od_a;   //如果i为偶数;则ev_ans需增加od_a的个数;
      }
      if(s[i] == ‘b‘)
      {
        ev_b++;
        od_ans += ev_b;
        ev_ans += od_b;
      }
    }
  }
  printf("%I64d %I64d\n", ev_ans, od_ans);
}

本题重点在于读过1次的字符不能再次搜索,在每一位都更新答案,并记录到本位与本位字符相同的奇数位字符次数,和偶数位次数。

转化与组合

原文:http://www.cnblogs.com/chenjiaqi-acm/p/4992684.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!