UVALive - 2965 Jurassic Remains
Input
Input consists of several datasets. The rst line of each dataset contains N | the number of bones
(1 ≤ N ≤ 24). Next N lines contain bones descriptions: each line contains a non-empty sequence of
different capital letters, representing labels marking the joints of the corresponding bone.
Output
For each dataset, on the rst line of the output le print L | the maximal possible number of bones
that could be used to reassemble skeleton fragments. After that, in another line, output L integer
numbers in ascending order | the bones to be used. Bones are numbered starting from one, as they
are given in the input le.
Sample Input
1
ABC
6
ABD
EG
GE
ABE
AC
BCD
Sample Output
0
5
1 2 3 5 6
都是偶数,应该想到异或,前n/2存入map,枚举后n/2,复杂度降为2^(n/2) lgn,密码学:中途相遇攻击
#include <cstdio> #include <algorithm> #include <iostream> #include <map> using namespace std; int A[25], n; map<int, int> table; string s; int bitCount(int xor_); int main() { while (scanf("%d", &n) == 1 && n) { for (int i = 0; i < n; ++i) { cin >> s; A[i] = 0; for (int j = 0; j < s.length(); ++j) { A[i] ^= 1 << s[j] - 'A'; //横向异或 } } int n1 = n >> 1, n2 = n - n1, ans = 0; table.clear(); 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(i) > bitCount(table[x])) { table[x] = i; } } for (int i = 0; i < 1 << n2; ++i) { int x = 0; for (int j = 0; j < n2; ++j) { if (i & 1 << j) { x ^= A[j + n1]; } } if (table.count(x) && bitCount(ans) < bitCount(i) + bitCount(table[x])) { ans = table[x] + (i << n1); } } cout << bitCount(ans) << endl; for (int i = 0; i < n; ++i) { if (ans & 1 << i) cout << i + 1 << " "; } cout << endl; } } int bitCount(int x) { //计算取了多少个数字 return x ? bitCount(x >> 1) + (x & 1) : 0; }