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;
}

 

posted @ 2017-11-12 23:49  少年啦飞驰  阅读(158)  评论(0编辑  收藏  举报