题目大意
有n个大写字母组成的字符串选择尽量多的串使得每个大写字母能能够出现偶数次。n<20
分析
在一个字符串中每个字母出现的次数无关紧要重要的是字母出现的奇偶性,我们正好可以用二进制表示每个字符串的奇偶性奇数对应1 偶数对应0
刘大神的代码一些地方不是特别懂,中途相遇法
#include<iostream>
#include<algorithm>
#include<map>
#define maxn 26
#define e <<endl
using namespace std;
map<int, int >table;
int bitcount(int x) //计算有几位集合;
{
return x == 0 ? 0 : bitcount(x / 2) + (x & 1);
}
int main()
{
int n;
int a[maxn];
while (cin >> n&&n!=0)
{
char ch[1000];
for (int i = 0; i < n; i++)
{
cin >> ch;
a[i] = 0;
for (int j = 0; ch[j]!='\0'; j++)
a[i] ^= (1<<(ch[j]-'A'));
}
table.clear();
int n1 = n / 2, n2 = n - n1;
for (int i = 0; i < (1 << n1); i++) //前一半;
{
int x = 0;
for (int j = 0; j < n1; j++)
if (i&(1 << j))
x ^= a[j];
if (!table.count(x) || bitcount(table[x]) < bitcount(i))
table[x] = i;
}
int ans = 0;
for (int i = 0; i < (1 << n2); i++)
{
//cout << "已执行" e;
int x = 0;
for (int j = 0; j < n2; j++)
if (i&(1 << j))
x ^= a[n1 + j];
//cout << x e; //困惑,有没有可能答案存在与后面n/2的字符串中,并且 有没有可能后面的n/2的x值前半边不存在呢,如果是这样的话,那就无法更新ans,也就无法得出最大值了呀
if (table.count(x) && bitcount(ans) < bitcount(table[x]) + bitcount(i))
{
ans = (i << n1) ^ x; //注意认真看,是谁在移动;
//cout << "已替换" << endl;
}
}
cout << bitcount(ans) << endl;
if (ans)
for ( int i = 0; i < n; i++)
if (ans&(1 << i))
cout << i+1 << " ";
cout << endl;
}
system("pause");
return 0;
}