題意:給出N個字符串(1 <= N <= 24),問最多可以找出多少個字符串,使得這些字符串中所有相同字符的個數和均爲偶數,並輸出是哪些字符串。
思路:把字符串分爲兩部分,分別枚舉狀態,並在map中查找後半部分的狀態是否在前半部分出現,從而達到枚舉全部子集的效果。
時間複雜度爲:O(2^(n/2) * log n)
#include <cstdio>
#include <map>
using namespace std;
const int N = 1000086, M = 33;
char s[N];
int st[M];
map<int, int> Map;
inline int count_bits(int x){ return __builtin_popcount(x); }
int main()
{
#ifdef LOCAL
freopen("in", "r", stdin);
#endif // LOCAL
int n;
while(~scanf("%d", &n)) {
Map.clear();
for(int i = 0; i < n; ++i) {
scanf("%s", s);
st[i] = 0;
for(int j = 0; s[j]; ++j) {
st[i] ^= (1 << (s[j] - 'A'));
}
}
int nn = n >> 1, nn1 = n - nn;
for(int i = 0; i < (1 << nn); ++i) {
int x = 0;
for(int j = 0; j < nn; ++j) {
if(i & (1 << j)) {
x ^= st[j];
}
}
if(!Map[x] || count_bits(i) > count_bits(Map[x])) Map[x] = i;
}
int ans = 0;
for(int i = 0; i < (1 << nn1); ++i) {
int x = 0;
for(int j = 0; j < nn1; ++j) {
if(i & (1 << j)) {
x ^= st[j + nn];
}
}
if((Map[x] || x == 0) && count_bits(Map[x]) + count_bits(i) > count_bits(ans)) ans = (i << nn) | Map[x];
}
printf("%d\n", count_bits(ans));
bool flag = 0;
for(int i = 0; i < n; ++i) {
if((1 << i) & ans) {
printf("%s%d", flag ? " " : "", i + 1);
flag = 1;
}
}
}
return 0;
}