题目

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 = ;
int n;
int a[MAXN];
int staStack[ << MAXN];
int posStack[ << MAXN]; int bone2sta(char * str) {
int sta = ;
for (char * p = str; *p != ; p++) {
sta ^= << (*p - 'A');
}
return sta;
} int getDigitCnt(int x) {
int ans = ;
while (x > ) {
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 = ;scanf("%d", &n) == && n; ti++) {
for (int i = ; i < n; i++) {
char buff[];
scanf("%s", buff);
a[i] = bone2sta(buff);
}
int half_n = n / ;
map<int, int> sta2pos;
sta2pos[] = ;
int staCnt = ;
staStack[staCnt++] = ;
for (int i = ; i < half_n; i++) {
for (int j = staCnt - ; j >= ; j--) {
posStack[j] = sta2pos[staStack[j]];
}
for (int j = staCnt - ; j >= ; j--) {
int sta = staStack[j];
int pos = posStack[j];
int newSta = sta ^ a[i];
int newPos = pos | ( << i);
if (sta2pos.count(newSta) == ) {
sta2pos[newSta] = newPos;
staStack[staCnt++] = newSta; }
else {
int oldDigitCnt = getDigitCnt(sta2pos[newSta]);
int newDigitCnt = getDigitCnt(pos) + ;
if(newDigitCnt > oldDigitCnt)sta2pos[newSta] = newPos;
}
}
}
map<int, int> othersta2pos;
othersta2pos[] = ;
staCnt = ;
staStack[staCnt++] = ;
for (int i = half_n; i < n; i++) {
for (int j = staCnt - ; j >= ; j--) {
posStack[j] = othersta2pos[staStack[j]];
}
for (int j = staCnt - ; j >= ; j--) {
int sta = staStack[j];
int pos = posStack[j];
int newSta = sta ^ a[i];
int newPos = pos | ( << i);
if (othersta2pos.count(newSta) == ) {
othersta2pos[newSta] = newPos;
staStack[staCnt++] = newSta; }
else {
int oldDigitCnt = getDigitCnt(othersta2pos[newSta]);
int newDigitCnt = getDigitCnt(pos) + ;
if (newDigitCnt > oldDigitCnt)othersta2pos[newSta] = newPos;
}
}
}
int ans = , ansPos = ;
for (int j = ; j < staCnt; j++) {
int sta = staStack[j];
if (sta2pos.count(sta) != ) {
int digitCnt = getDigitCnt(sta2pos[sta]) + getDigitCnt(othersta2pos[sta]);
if (digitCnt > ans) {
ans = digitCnt;
ansPos = sta2pos[sta] | othersta2pos[sta];
}
}
}
printf("%d\n", ans);
for (int i = ; i < n; i++) {
if (ansPos & ( << i)) {
printf("%d ", i + );
}
}
puts("");
} return ;
}

UVa LA 2965 - Jurassic Remains 中间相遇,状态简化 难度: 2的更多相关文章

  1. LA 2965 Jurassic Remains (中途相遇法)

    Jurassic Remains Paleontologists in Siberia have recently found a number of fragments of Jurassic pe ...

  2. LA 2965 Jurassic Remains

    这是我做的第一道状态压缩的题目,而且我自己居然看懂了,理解得还算透彻. 题意:给出若干个大写字母组成的字符串,然后选取尽量多的字符串使得这些字母出现偶数次. 最朴素的想法,穷举法:每个字符串只有选和不 ...

  3. UVALive - 2965 Jurassic Remains (LA)

    Jurassic Remains Time Limit: 18000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu [Sub ...

  4. 【UVALive】2965 Jurassic Remains(中途相遇法)

    题目 传送门:QWQ 分析 太喵了~~~~~ 还有中途相遇法这种东西的. 嗯 以后可以优化一些暴力 详情左转蓝书P58 (但可能我OI生涯中都遇不到正解是这个的题把...... 代码 #include ...

  5. UVaLive 2965 Jurassic Remains (状态压缩)

    题意:给定 n 个大写字母组成的字符串,选择尽量多的串,使得大写字母都能出现偶数次. 析:由于n比较小,我们可以枚举前n/2的所有组合,然后再从后面查找. 代码如下: #pragma comment( ...

  6. uvalive 2965 Jurassic Remains

    https://vjudge.net/problem/UVALive-2965 题意: 给出若干个由大写字母组成的字符串,要求选出尽量多的字符串,使得每个大写字母出现的次数是偶数. 思路: 如果说我们 ...

  7. 【中途相遇+二进制】【NEERC 2003】Jurassic Remains

    例题25  侏罗纪(Jurassic Remains, NEERC 2003, LA 2965) 给定n个大写字母组成的字符串.选择尽量多的串,使得每个大写字母都能出现偶数次. [输入格式] 输入包含 ...

  8. Meeting-in-the-Middle (LA 2965)

    Meeting-in-the-Middle,又称“中途相遇法”.准确地说,它只是一种策略. 顺便说一下,这个算法真的很冷门! 结合这道题来讨论一下吧:LA 2965.ε(┬┬﹏┬┬)3 因为博主的英文 ...

  9. UVA LA 7146 2014上海亚洲赛(贪心)

    option=com_onlinejudge&Itemid=8&page=show_problem&category=648&problem=5158&mosm ...

随机推荐

  1. SpringBoot简单的REST风格例子

    关于REST和RESTful的说明请移步至:怎样用通俗的语言解释REST,以及RESTful? 其实我自己也不是十分的理解,只是今天学SpringBoot时看到有个标着REST风格的简单例子,就记录一 ...

  2. 求文件的hash值(基于SHA3的Hash)

    import hashlib import tkinter from tkinter import filedialog import pyperclip def fileHash(fileName) ...

  3. leecode第五十九题(螺旋矩阵 II)

    class Solution { public: vector<vector<int>> generateMatrix(int n) { )//特殊情况 { vector< ...

  4. 《剑指offer》第五十三题(0到n-1中缺失的数字)

    // 面试题53(二):0到n-1中缺失的数字 // 题目:一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字 // 都在范围0到n-1之内.在范围0到n-1的n个数字中有且只有一个数 ...

  5. MYSQL的常用函数(字符串函数)

    ASCII(char)返回字符的ASCII码值 BIT_LENGTH(str)返回字符串的比特长度 CONCAT(s1,s2...,sn)将s1,s2...,sn连接成字符串 CONCAT_WS(se ...

  6. 不要在Lua中使用os.clock()函数

    1.os.clock函数的实现是调用了c语言的函数函数库,实现代码如下: static int os_clock (lua_State *L) { lua_pushnumber(L, ((lua_Nu ...

  7. 绕过cookies进行登录并封装请求方法

    之前写了一篇使用session跨请求保持会话的帖子,这次在它的基础上对请求方法简单封装一下,可以达到复用的效果 1.先定义登录方法 在登录方法中利用session跨请求保持会话,并返回session, ...

  8. [Spring] ClassPathXmlApplicationContext类

    1. 该类在package org.springframework.context.support包下. 该包在4.0.1中封装在spring-context-***.jar中. 其无参构造函数的文档 ...

  9. eclipse 快捷键Open Implementation 直接退出

    遇到eclipse 快捷键Open  Implementation 非正常退出.直接关闭的现象. 网查了一下   碰到一篇博客说  和google 输入法有关  卸载了google 输入法就好了 半信 ...

  10. Python while循环实现重试

    try: pass#要执行的代码 except: 状态=True while 状态==True: try: winsound.Beep(800, 1000)#报警提示音 循环=300 while 循环 ...