UVa 1326 - Jurassic Remains(枚举子集+中途相遇法)

训练指南p.59

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <map>



using namespace std;



const int MAXN = 30;



int N;

int A[MAXN];

char str[1010];

map<int , int> table;



int bitcount( int x )

{

    int res = 0;

    while ( x )

    {

        if ( x & 1 ) ++res;

        x >>= 1;

    }

    return res;

}



int main()

{

    while ( scanf( "%d", &N ) == 1 )

    {

        for ( int i = 0; i < N; ++i )

        {

            scanf( "%s", str );

            A[i] = 0;

            for ( int j = 0; str[j]; ++j )

                A[i] |= ( 1 << ( str[j] - 'A' ) );

        }



        table.clear();



        int n1 = N / 2, n2 = N - n1;

        for ( int i = 0; i < ( 1 << n1 ); ++i )

        {

            int tmp = 0;

            for ( int j = 0; j < n1; ++j )

            if ( i & ( 1 << j ) )

                tmp ^= A[j];

            if ( !table.count(tmp) || bitcount(i) > bitcount( table[tmp] ) ) table[tmp] = i;

        }



        int ans = 0;

        for ( int i = 0; i < ( 1 << n2 ); ++i )

        {

            int tmp = 0;

            for ( int j = 0; j < n2; ++j )

            if ( i & ( 1 << j ) ) tmp ^= A[ n1 + j ];

            if ( table.count(tmp) && bitcount(ans) < bitcount(i) + bitcount(table[tmp]) )

                ans = ( i << n1 ) | table[tmp];

        }



        printf("%d\n", bitcount(ans) );

        bool first = false;

        for ( int i = 0; i < N; ++i )

        if ( ans & ( 1 << i ) )

        {

            if ( first ) putchar(' ');

            printf("%d", i + 1);

            first = true;

        }

        puts("");

    }

    return 0;

}

 

你可能感兴趣的:(main)