中途相遇法,子集我使用dfs枚举的,稍微慢一点,但是不会超时。
#include <stdio.h>
#include <string.h>
#include <vector>
#include <map>
using namespace std;
const int max_n = 5000+10;
char buf[max_n];
int value[25];
typedef int NUMBER;
typedef int INDEX;
map<NUMBER, vector<INDEX> > m;
map<NUMBER, vector<INDEX> > max_result;
vector<INDEX> max_vector;
int str2num(const char *str){
int len, i;
int base, sum;
len = strlen(str);
unsigned char arr[27];
memset(arr, 0, 27);
for(i=0; i<len; i++){
arr[buf[i]-'A']++;
arr[buf[i]-'A'] %= 2;
}
base = 1;
sum = 0;
for(i=0; i<26; i++){
if(arr[i])
sum += base;
base <<= 1;
}
return sum;
}
void dfs(int cur, int max_index, int last_xor, const vector<int> last_set){
int cur_xor;
vector<int> cur_set;
if(last_set.size())
cur_xor = last_xor ^ value[cur];
else
cur_xor = value[cur];
cur_set = last_set;
cur_set.push_back(cur);
if(m.find(cur_xor) == m.end()){
m[cur_xor] = cur_set;
}
else{
if(m[cur_xor].size() < cur_set.size())
m[cur_xor] = cur_set;
}
if(cur != max_index)
dfs(cur+1, max_index, cur_xor, cur_set);
cur_xor = last_xor;
cur_set = last_set;
if(cur == max_index && cur_set.size()==0){
cur_xor = 0;
cur_set.clear();
if(m.find(cur_xor) == m.end()){
m[cur_xor] = cur_set;
}
else{
if(m[cur_xor].size() < cur_set.size())
m[cur_xor] = cur_set;
}
}
if(cur != max_index)
dfs(cur+1, max_index, cur_xor, cur_set);
}
void dfs_find_max(int cur, int max_index, int last_xor, const vector<int> last_set){
int cur_xor, i;
vector<int> cur_set;
vector<int> sum_v;
if(last_set.size())
cur_xor = last_xor ^ value[cur];
else
cur_xor = value[cur];
cur_set = last_set;
cur_set.push_back(cur);
if(m.find(cur_xor) != m.end()){
sum_v = m[cur_xor];
for(i=0; i<cur_set.size(); i++)
sum_v.push_back(cur_set[i]);
if(max_result.find(cur_xor) == max_result.end()){
max_result[cur_xor] = sum_v;
}
else{
if(max_result[cur_xor].size() < sum_v.size())
max_result[cur_xor] = sum_v;
}
if(max_vector.size() < max_result[cur_xor].size())
max_vector = max_result[cur_xor];
}
if(cur != max_index)
dfs_find_max(cur+1, max_index, cur_xor, cur_set);
cur_xor = last_xor;
cur_set = last_set;
if(cur == max_index && cur_set.size()==0){
cur_xor = 0;
cur_set.clear();
if(m.find(cur_xor) != m.end()){
sum_v = m[cur_xor];
for(i=0; i<cur_set.size(); i++)
sum_v.push_back(cur_set[i]);
if(max_result.find(cur_xor) == max_result.end()){
max_result[cur_xor] = sum_v;
}
else{
if(max_result[cur_xor].size() < sum_v.size())
max_result[cur_xor] = sum_v;
}
if(max_vector.size() < max_result[cur_xor].size())
max_vector = max_result[cur_xor];
}
}
if(cur != max_index)
dfs_find_max(cur+1, max_index, cur_xor, cur_set);
}
void func(int n){
int i;
vector<int> v;
if(1 == n){
if(value[1]){
printf("%d\n\n", 0);
}
else{
printf("%d\n", 1);
printf("%d\n", 1);
}
return;
}
m.clear();
max_result.clear();
max_vector.clear();
v.clear();
dfs(1, n/2, value[1], v);
v.clear();
dfs_find_max(n/2+1, n, value[n/2+1], v);
printf("%d\n", max_vector.size());
for(i=0; i<max_vector.size(); i++){
printf(0==i ? "%d" : " %d", max_vector[i]);
}
printf("\n");
}
int main(void){
int n, i;
//freopen("input.dat", "r", stdin);
//freopen("output.dat", "w", stdout);
while(scanf("%d", &n) != EOF){
for(i=1; i<=n; i++){
scanf("%s", buf);
value[i] = str2num(buf);
}
func(n);
}
return 0;
}