【AtCoder CODE FESTIVAL 2017 qual C】D

来源:互联网 发布:灯具品牌 知乎 编辑:程序博客网 时间:2024/05/23 11:32

D - Yet Another Palindrome Partitioning


Time limit : 3sec / Memory limit : 512MB

Score : 700 points

Problem Statement

We have a string s consisting of lowercase English letters. Snuke is partitioning s into some number of non-empty substrings. Let the subtrings obtained be s1s2sN from left to right. (Here, s=s1+s2++sN holds.) Snuke wants to satisfy the following condition:

  • For each i (1iN), it is possible to permute the characters in si and obtain a palindrome.

Find the minimum possible value of N when the partition satisfies the condition.

Constraints

  • 1|s|2×105
  • s consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

s

Output

Print the minimum possible value of N when the partition satisfies the condition.


Sample Input 1

Copy
aabxyyzz

Sample Output 1

Copy
2

The solution is to partition s as aabxyyzz = aab + xyyzz. Here, aab can be permuted to form a palindrome aba, and xyyzz can be permuted to form a palindrome zyxyz.


Sample Input 2

Copy
byebye

Sample Output 2

Copy
1

byebye can be permuted to form a palindrome byeeyb.


Sample Input 3

Copy
abcdefghijklmnopqrstuvwxyz

Sample Output 3

Copy
26

Sample Input 4

Copy
abcabcxabcx

Sample Output 4

Copy
3

The solution is to partition s as abcabcxabcx = a + b + cabcxabcx.


#include <bits/stdc++.h>  using namespace std;  string s;  unordered_map<int, int>cnt;  int main(){  cin>>s;  int cur = 0, x;  cnt[cur] = 1;  for(int i = 0; i < s.size(); ++i){  cur ^= (1 << (s[i] - 'a'));  if(cur ==  0){  continue;  }  else{  x = 1e8;  if(cnt[cur] > 0){  x= min(x, cnt[cur]);  }  for(int j = 0; j < 26; ++j){  if((cur ^ (1 << j)) == 0){ x = 1; break;}  else{  if(cnt[cur ^ (1 << j)] > 0) x = min(x, cnt[cur ^ (1 << j)] + 1);  else{  x = min(x, cnt[cur ^ (1 << (s[i] - 'a'))] + 1);  }  }  }  cnt[cur] = x;  }  }  cout << cnt[cur] << endl;  }     /* 题意: 长度2e5的字符串,问最少需要分成多少个连续的子串,在子串内部的字符可以随意排列的情况下使得这些子串都是回文串。   思路:对于子串,只要出现奇数次的字符不超过1个,该子串就是回文串。一共26个小写字母,可以用一个整数状压记录,第i 位表示该字母出现多少次。某位为0表示出现偶数次,为1表示出现奇数次。这样就很容易维护答案了。 */