UVa LA 2965 - Jurassic Remains 中间相遇,状态简化 难度: 2
题目
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的更多相关文章
- LA 2965 Jurassic Remains (中途相遇法)
Jurassic Remains Paleontologists in Siberia have recently found a number of fragments of Jurassic pe ...
- LA 2965 Jurassic Remains
这是我做的第一道状态压缩的题目,而且我自己居然看懂了,理解得还算透彻. 题意:给出若干个大写字母组成的字符串,然后选取尽量多的字符串使得这些字母出现偶数次. 最朴素的想法,穷举法:每个字符串只有选和不 ...
- UVALive - 2965 Jurassic Remains (LA)
Jurassic Remains Time Limit: 18000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu [Sub ...
- 【UVALive】2965 Jurassic Remains(中途相遇法)
题目 传送门:QWQ 分析 太喵了~~~~~ 还有中途相遇法这种东西的. 嗯 以后可以优化一些暴力 详情左转蓝书P58 (但可能我OI生涯中都遇不到正解是这个的题把...... 代码 #include ...
- UVaLive 2965 Jurassic Remains (状态压缩)
题意:给定 n 个大写字母组成的字符串,选择尽量多的串,使得大写字母都能出现偶数次. 析:由于n比较小,我们可以枚举前n/2的所有组合,然后再从后面查找. 代码如下: #pragma comment( ...
- uvalive 2965 Jurassic Remains
https://vjudge.net/problem/UVALive-2965 题意: 给出若干个由大写字母组成的字符串,要求选出尽量多的字符串,使得每个大写字母出现的次数是偶数. 思路: 如果说我们 ...
- 【中途相遇+二进制】【NEERC 2003】Jurassic Remains
例题25 侏罗纪(Jurassic Remains, NEERC 2003, LA 2965) 给定n个大写字母组成的字符串.选择尽量多的串,使得每个大写字母都能出现偶数次. [输入格式] 输入包含 ...
- Meeting-in-the-Middle (LA 2965)
Meeting-in-the-Middle,又称“中途相遇法”.准确地说,它只是一种策略. 顺便说一下,这个算法真的很冷门! 结合这道题来讨论一下吧:LA 2965.ε(┬┬﹏┬┬)3 因为博主的英文 ...
- UVA LA 7146 2014上海亚洲赛(贪心)
option=com_onlinejudge&Itemid=8&page=show_problem&category=648&problem=5158&mosm ...
随机推荐
- Hadoop大数据分析应用场景
J 为了满足日益增长的业务变化,京东的京麦团队在京东大数据平台的基础上,采用了hadoop等热门的开源大数据计算引擎,打造了一款为京东运营和产品提供决策性的数据类产品-北斗平台. 一.Hadoop的应 ...
- ThinkPHP实用项
跟踪信息 – 两种模式 – Sql调试 – 性能调试
- mongodb分享(二)
上次讲的:查询find\findone\pretty.条件操作符 (大于.小于.大于等于.小于等于.不等于,$type).limit\skip.sort.Db.postjson.getIndexes( ...
- 雷林鹏分享:C# 环境
C# 环境 在这一章中,我们将讨论创建 C# 编程所需的工具.我们已经提到 C# 是 .Net 框架的一部分,且用于编写 .Net 应用程序.因此,在讨论运行 C# 程序的可用工具之前,让我们先了解一 ...
- 用ActionController::Renderer的render方法渲染模版
使用Cable进行pub: ActionCable.server.broadcast "call", {address: AddressesController.render(@a ...
- p1530 Fractions to Decimals
将余数记录下来,如果余数相同,那么商的下一位也相同. #include <iostream> #include <cstdio> #include <cmath> ...
- 2.3 UML活动图
活动图定义 活动图描述了在一个过程中,顺序的/并行的活动及其之间的关系 应用于商业过程.工作流(业务过程).复杂算法的建模 活动图是顶点和弧的集合 活动节点 动作 流 对象值 注解和约束等 活动图基本 ...
- 非常可乐 HDU - 1495
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为.因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多.但see ...
- Linux中man手册的使用
Linux中man手册的使用 ——以CentOS6.8为例 本文旨在介绍在Linux中如何快速入手新命令,毕竟在Linux系统中,可以通过命令完成一切操作. 相关命令:help man whatis ...
- loj#528. 「LibreOJ β Round #4」求和
求:\(\sum_{i=1}^n\sum_{j=1}^m\mu(gcd(i,j))^2\) 化简可得\(\sum_{i=1}^{min(n,m)}{\lfloor \frac{n}{i} \rfloo ...