zoukankan      html  css  js  c++  java
  • UVa LA 2965

    题目

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=966


    题意

    n个大写字母串(n <= 24),问最多取多少个,使得所有字符出现的次数都是偶数。

    思路

    如刘书

    1. 由于最多出现26个字母,而且字母在字符串中出现的次数本身不重要,只要记录奇偶性,所以可以将这些字符串转化为01串便于存储。

    2. 问题转化为最多取多少个01串,使得其异或结果为0

    3. 这样就可以用2^24来枚举,但这样状态还是太多了

    4. 问题可以转化为前n/2个字符串子集组成的异或结果与后n/2个字符串子集组成的异或结果相同的情况下,最多取多少个字符串。

    感想

    1. 一开始忘了字符串本身可能存在重复的字符串

    2. 之后忘了程序会修改pos

    代码

    #include <algorithm>
    #include <cassert>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <map>
    #include <queue>
    #include <set>
    #include <string>
    #include <tuple>
    #define LOCAL_DEBUG
    using namespace std;
    const int MAXN = 24;
    int n;
    int a[MAXN];
    int staStack[1 << MAXN];
    int posStack[1 << MAXN];
    
    int bone2sta(char * str) {
        int sta = 0;
        for (char * p = str; *p != 0; p++) {
            sta ^= 1 << (*p - 'A');
        }
        return sta;
    }
    
    int getDigitCnt(int x) {
        int ans = 0;
        while (x > 0) {
            x -= (x & -x);
            ans++;
        }
        return ans;
    }
    
    int main() {
    #ifdef LOCAL_DEBUG
        freopen("C:\Users\Iris\source\repos\ACM\ACM\input.txt", "r", stdin);
        freopen("C:\Users\Iris\source\repos\ACM\ACM\output.txt", "w", stdout);
    #endif // LOCAL_DEBUG
        //int T;
    //    scanf("%d", &T);
    
        for (int ti = 1;scanf("%d", &n) == 1 && n; ti++) {
            for (int i = 0; i < n; i++) {
                char buff[27];
                scanf("%s", buff);
                a[i] = bone2sta(buff);
            }
            int half_n = n / 2;
            map<int, int> sta2pos;
            sta2pos[0] = 0;
            int staCnt = 0;
            staStack[staCnt++] = 0;
            for (int i = 0; i < half_n; i++) {
                for (int j = staCnt - 1; j >= 0; j--) {
                    posStack[j] = sta2pos[staStack[j]];
                }
                for (int j = staCnt - 1; j >= 0; j--) {
                    int sta = staStack[j];
                    int pos = posStack[j];
                    int newSta = sta ^ a[i];
                    int newPos = pos | (1 << i);
                    if (sta2pos.count(newSta) == 0) {
                        sta2pos[newSta] = newPos;
                        staStack[staCnt++] = newSta;
                        
                    }
                    else {
                        int oldDigitCnt = getDigitCnt(sta2pos[newSta]);
                        int newDigitCnt = getDigitCnt(pos) + 1;
                        if(newDigitCnt > oldDigitCnt)sta2pos[newSta] = newPos;
                    }
                }
            }
            map<int, int> othersta2pos;
            othersta2pos[0] = 0;
            staCnt = 0;
            staStack[staCnt++] = 0;
            for (int i = half_n; i < n; i++) {
                for (int j = staCnt - 1; j >= 0; j--) {
                    posStack[j] = othersta2pos[staStack[j]];
                }
                for (int j = staCnt - 1; j >= 0; j--) {
                    int sta = staStack[j];
                    int pos = posStack[j];
                    int newSta = sta ^ a[i];
                    int newPos = pos | (1 << i);
                    if (othersta2pos.count(newSta) == 0) {
                        othersta2pos[newSta] = newPos;
                        staStack[staCnt++] = newSta;
    
                    }
                    else {
                        int oldDigitCnt = getDigitCnt(othersta2pos[newSta]);
                        int newDigitCnt = getDigitCnt(pos) + 1;
                        if (newDigitCnt > oldDigitCnt)othersta2pos[newSta] = newPos;
                    }
                }
            }
            int ans = 0, ansPos = 0;
            for (int j = 0; j < staCnt; j++) {
                int sta = staStack[j];
                if (sta2pos.count(sta) != 0) {
                    int digitCnt = getDigitCnt(sta2pos[sta]) + getDigitCnt(othersta2pos[sta]);
                    if (digitCnt > ans) {
                        ans = digitCnt;
                        ansPos = sta2pos[sta] | othersta2pos[sta];
                    }
                }
            }
            printf("%d
    ", ans);
            for (int i = 0; i < n; i++) {
                if (ansPos & (1 << i)) {
                    printf("%d ", i + 1);
                }
            }
            puts("");
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    路飞学城-Python开发集训-第3章
    路飞学城-Python开发集训-第2章
    路飞学城-Python开发集训-第1章
    Python:Day55 ORM多表操作
    Python:Day54 ORM
    Django的auth【认证】模块简介
    importlib的用法
    Django中的forms一些小点
    利用xlrd模块读取excel利用json模块生成相应的json文件的脚本
    json的内容回顾
  • 原文地址:https://www.cnblogs.com/xuesu/p/10416961.html
Copyright © 2011-2022 走看看