LA_2965 Jurassic Remains

題意:
給定n個大寫字母組成的字符串,選擇儘量多的串,使得每個大寫字母都能出現偶數次
分析:
不難想出枚舉每個字符串選擇與否的暴力算法可惜運算量高達2^24
由於字符串只考慮每個字母的奇偶情況,用0表示字符出現的次數爲偶數,1表示出現的次數爲基數,可以使用stl中的map建立前n/2個字符串所有情況的映射,然後枚舉後n個的時候可以從映射中二分查找
Code:
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;


#define DIR     4
#define DIM     2
#define STATUS  2
#define MAXBIT  24
#define MAXN    20 + 10
#define MAXM    100000 + 10
#define oo      (~0u)>>1
#define INF     0x3F3F3F3F
#define REPI(i, s, e)   for(int i = s; i <= e; i ++)
#define REPD(i, e, s)   for(int i = e; i >= s; i --)


static const double EPS = 1e-5;


char str[MAXN];
int f[MAXN];
map<int, int> hash;
map<int, int>::iterator it;


int count_bit(int value)
{
        if( !value ) {
                return 0;
        }
        return count_bit(value>>0x1)+(value&1);
}


int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
        freopen("test.in", "r", stdin);
#endif
        int n;
        while( ~scanf("%d", &n) ) {
                hash.clear();
                REPI(i, 1, n) {
                        scanf("%s", str);
                        f[i] = 0;
                        REPI(j, 0, strlen(str)-1) {
                                f[i] ^= (1<<(str[j]-'A'));
                        }
                }


                //enum the first part, n/2
                int n1 = n>>0x1;
                int value;
                REPI(i, 0, (1<<n1)-1) {
                        value = 0;
                        REPI(j, 0, n1-1) {
                                if( i&(1<<j) ) {        //select (j+1)
                                        value ^= f[j+1];
                                }
                        }
                        it = hash.find(value);
                        if( it == hash.end() ) {
                                hash.insert(map<int, int>::value_type(value, i));
                        }
                        else if( count_bit(it->second) < count_bit(i) ) {
                                it->second = i;
                        }
                }


                // //enum the second part.
                int n2 = n-n1;
                int count = 0, lans = 0, rans = 0;
                REPI(i, 0, (1<<n2)-1) {
                        value = 0;
                        REPI(j, 0, n2-1) {
                                if( i&(1<<j) ) {
                                        value ^= (f[n1+j+1]);
                                }
                        }
                        it = hash.find(value);
                        if( it == hash.end() ) {
                                continue;
                        }
                        int tmp = count_bit(it->second)+count_bit(i);
                        if( count < tmp ) {
                                lans = it->second, rans = i;
                                count = tmp; 
                        }
                }


                //output ans.
                printf("%d\n", count);
                REPI(i, 0, n1-1) {
                        if( lans&(1<<i) ) {
                                printf("%d ", i+1);
                        }
                }
                REPI(i, 0, n2-1) {
                        if( rans&(1<<i) ) {
                                printf("%d ", n1+i+1);
                        }
                }
                printf("\n");
        }
        return 0;
}

發佈了193 篇原創文章 · 獲贊 0 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章