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 ...
随机推荐
- IPC 之 Binder 初识
概述 最近在看Android 的 IPC 机制,想要系统的研究一下,然后就走到了 Binder 这里,发现这个东西真是复杂,查看了一下些文章想要记录下.想要自己写但是发现一篇文章已经写的非常好了,就转 ...
- java类加载器和双亲委派模型
一. 类加载器 ClassLoader即常说的类加载器,其功能是用于从Class文件加载所需的类,主要场景用于热部署.代码热替换等场景. 系统提供3种的类加载器:Bootstrap ClassLoad ...
- leecode第五十三题(最大子序和)
class Solution { public: int maxSubArray(vector<int>& nums) { int len=nums.size(); )//特殊情况 ...
- 获取 ip ( 第三方接口 )
搜狐IP地址查询接口(默认GBK):http://pv.sohu.com/cityjson 搜狐IP地址查询接口(可设置编码):http://pv.sohu.com/cityjson?ie=utf-8 ...
- vue-cli3+cordova实现app混合开发
一.安装vue-cli3 安装并建新项目 二.进入项目安装cordova npm install -g cordova 下载完之后,输入 cordova -v 查看是否成功安装,出现相应的版本号则成功 ...
- jGrid + echart 后台管理
用来初始化表的大小: $(select_dom).jqGrid( 'setGridWidth', parent_column.width() ); 表的大小随着页面的宽度变化: $(window).o ...
- 通过cookies跳过验证码登陆页面,直接访问网站的其它URL
我每次手动访问去NN网的一家酒店,就不需要登陆,一旦我用脚本打开就会让我登陆,而登陆页面又有验证码,不想识别验证码,所以就想:“通过cookies跳过验证码登陆页面,直接访问网站的其它URL” 转 ...
- 雷林鹏分享:jQuery EasyUI 树形菜单 - 树形网格动态加载
jQuery EasyUI 树形菜单 - 树形网格动态加载 动态加载树形网格有助于从服务器上加载部分的行数据,避免加载大型数据的长时间等待.本教程将向您展示如何创建带有动态加载特性的树形网格(Tree ...
- Using the G711 standard
Using the G711 standard Marc Sweetgall, 28 Jul 2006 4.74 (27 votes) 1 2 ...
- python安装pandas和lxml
一.安装python 二.安装pip 三.安装mysql-connector(window版):下载mysql-connector-python-2.1.3,解压后进入目录,命令安装:pip inst ...