题目链接:点击打开链接
题意:给定n个字符串,选尽可能多的字符串使得每种字母出现的次数为偶数次
思路:
中途相遇法
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Queue;
public class Main {
class Node implements Comparable<Node>{
int state, num;
Node(){}
Node(int state, int num){
this.state = state; this.num = num;
}
public int compareTo(Node o) {
return Integer.compare(state, o.state);
}
public Node clone(){
return new Node(state, num);
}
}
static int N = 25;
int n;
int[] a = new int[N];
TreeMap<Integer,Integer> b = new TreeMap();
int One(int x){
int ans = 0;
while(x>0){
ans++;
x&=x-1;
}
return ans;
}
int ans;
void input(){
n = cin.nextInt();
for(int i = 0; i < n; i++){
String s = "1";
while(s.charAt(0)<'A'||s.charAt(0)>'Z')s = cin.next();
a[i] = 0;
for(int j = 0; j < s.length(); j++)
a[i]^=(1<<(s.charAt(j)-'A'));
}
b.clear();
for(int i = 0; i < (1<<(n/2)); i++)
{
int tmp = 0;
for(int j = 0; j < (n/2); j++)
if((i&(1<<j)) > 0)
tmp ^= a[j];
if(!b.containsKey(tmp) || One(i) > One(b.get(tmp)))
b.put(tmp, i);
}
}
void work() {
while (cin.hasNext()) {
ans = 0;
input();
for(int i = 0; i < (1<<(n-n/2)); i++)
{
int tmp = 0;
for(int j = 0; j < n-n/2; j++)
if((i&(1<<j))>0)
tmp ^= a[j+n/2];
if(b.containsKey(tmp) && One(i) + One(b.get(tmp)) > One(ans))
ans = (i<<(n/2)) ^ b.get(tmp);
}
out.println(One(ans));
for(int j = 0; j < n; j++)
if((ans&(1<<j))>0)
out.print((j+1)+" ");
out.println();
}
}
Main() {
cin = new Scanner(System.in);
out = new PrintWriter(System.out);
}
public static void main(String[] args) {
Main e = new Main();
e.work();
out.close();
}
public Scanner cin;
public static PrintWriter out;
}