【中途相遇+二进制】【NEERC 2003】Jurassic Remains
例题25 侏罗纪(Jurassic Remains, NEERC 2003, LA 2965)
给定n个大写字母组成的字符串。选择尽量多的串,使得每个大写字母都能出现偶数次。
【输入格式】
输入包含多组数据。每组数据的第一行为正整数n(1≤n≤24),以下n行每行包含一个大写字母组成的字符串。
【输出格式】
对于每组数据,第一行输出整数k,即字符串个数的最大值。第二行按照从小到大的顺序输出选中的k个字符串的编号(字符串按照输入顺序编号为1~n)。
【样例输入】
6
ABD
EG
GE
ABE
AC
BCD
【样例输出】
5
1 2 3 5 6
直接贴题解吧
在一个字符串中,每个字符出现的次数本身是无关紧要的,重要的只是这些次数的奇偶性,因此想到用一个二进制的位表示一个字母(1表示出现奇数次,0表示出现偶数次)。比如样例的6个数,写成二进制后如图1-34所示。
图 1-34
此时,问题转化为求尽量多的数,使得它们的xor(异或)值为0。
最容易想到的方法是直接穷举,时间复杂度为O(2n),有些偏大。注意到xor值为0的两个整数必须完全相等,我们可以把字符串分成两个部分:首先计算前n/2个字符串所能得到的所有xor值,并将其保存到一个映射S(xor值à前n/2个字符串的一个子集)中;然后枚举后n/2个字符串所能得到的所有xor值,并每次都在S中查找。
如果映射用STL的map实现,总时间复杂度为O(2n/2logn),即O(1.44nlogn),比第一种方法好了很多。这样的策略称为中途相遇法(Meet-in-the-Middle)。密码学中著名的中途相遇攻击(Meet-in-the-Middle attack)就是基于这个原理。
#include<cstdio>
#include<map>
using namespace std; const int maxn = 24;
map<int,int> table; int bitcount(int x) { return x == 0 ? 0 :bitcount(x/2) + (x&1); } int main() {
int n,A[maxn];
chars[1000]; while(scanf("%d", &n) == 1 && n) {
//输入并计算每个字符串对应的位向量
for(int i= 0; i < n; i++) {
scanf("%s", s);
A[i] =0;
for(intj = 0; s[j] != '\0'; j++) A[i] ^= (1<<(s[j]-'A'));
}
//计算前n1个元素的所有子集的xor值
//table[x]保存的是xor值为x的,bitcount尽量大的子集
table.clear();
int n1 =n/2, n2 = n-n1;
for(int i= 0; i < (1<<n1); i++) {
int x =0;
for(intj = 0; j < n1; j++) if(i & (1<<j)) x ^= A[j];
if(!table.count(x) || bitcount(table[x]) < bitcount(i)) table[x] = i;
}
//枚举后n2个元素的所有子集,并在table中查找
int ans =0;
for(int i= 0; i < (1<<n2); i++) {
int x =0;
for(intj = 0; j < n2; j++) if(i & (1<<j)) x ^= A[n1+j];
if(table.count(x)&&bitcount(ans)<bitcount(table[x])+bitcount(i))ans = (i<<n1)^table[x];
}
//输出结果
printf("%d\n", bitcount(ans));
for(int i= 0; i < n; i++) if(ans & (1<<i)) printf("%d ", i+1);
printf("\n");
}
return 0;
}
几个位运算以及STL巧妙运用注意注意
int bitcount(int x) //计算一串数的二进制还有的1的个数
table.count(x)//判断x是否为控
ans = (i<<n1)^table[x];//合并i与x 两个二进制代表的集合
【中途相遇+二进制】【NEERC 2003】Jurassic Remains的更多相关文章
- LA 2965 Jurassic Remains (中途相遇法)
Jurassic Remains Paleontologists in Siberia have recently found a number of fragments of Jurassic pe ...
- 【UVALive】2965 Jurassic Remains(中途相遇法)
题目 传送门:QWQ 分析 太喵了~~~~~ 还有中途相遇法这种东西的. 嗯 以后可以优化一些暴力 详情左转蓝书P58 (但可能我OI生涯中都遇不到正解是这个的题把...... 代码 #include ...
- UVALive - 2965 Jurassic Remains (LA)
Jurassic Remains Time Limit: 18000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu [Sub ...
- 【中途相遇法】【STL】BAPC2014 K Key to Knowledge (Codeforces GYM 100526)
题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show& ...
- 【UVALive2965】Jurassic Remains
题意 题意给定n个大写字母组成的字符串,选择尽量多的串,使得每个大写字母都能出现偶数次.n<=24,每个字符串中每个字母最多出现一次. 分析 这是训练指南上的一道中途相遇法的简单题,但是好像也能 ...
- LA 2965 中途相遇法
题目链接:https://vjudge.net/problem/UVALive-2965 题意: 有很多字符串(24),选出一些字符串,要求这些字符串的字母都是偶数次: 分析: 暴力2^24也很大了, ...
- 中途相遇法 解决 超大背包问题 pack
Description [题目描述] 蛤布斯有n个物品和一个大小为m的背包,每个物品有大小和价值,它希望你帮它求出背包里最多能放下多少价值的物品. [输入数据] 第一行两个整数n,m.接下来n行每行两 ...
- uva 6757 Cup of Cowards(中途相遇法,貌似)
uva 6757 Cup of CowardsCup of Cowards (CoC) is a role playing game that has 5 different characters (M ...
- HDU 5936 Difference 【中途相遇法】(2016年中国大学生程序设计竞赛(杭州))
Difference Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
随机推荐
- CCA概述和安装
什么是CCA? 客户关怀加速器(CCA)为微软动态®CRM通过集中的客户信息从不同的系统在一个集成代理桌面促进剂的效率和有效性. CCA是一个參考应用,利用用户界面集成(UII)为微软Dynamics ...
- POJ 3694 LCA
题意:有N台电脑,他们之间有M条无向边. 然后询问,每次在他们之间加一条边,剩余的桥有多少. 思路:其实这题都不需要缩点了.. 直接记录每条桥的位置,然后每次询问进行一次LCA,当询问到桥时,桥数减1 ...
- ProFTPD“killed (signal 15)”自动退出问题解决
proftpd服务端每隔几天就重启一次,日志如下: 看起来这又像是一个仅有两行日志的无头案了.不过由于日志明确给出了退出信号“killed (signal 15)”,因此Google的话还是比较简单找 ...
- JQuery hover(over,out) 使用笔记
转载自:http://www.douban.com/note/202404884/ JQuery hover(over,out) 使用笔记 JavaScript 下.onmouseover() 和 o ...
- linux基础内容学习一:linux下的分区及安装
linux看系统版本信息 uname -a 如果显示为i386,i686则为32位系统,如果为x86_64则为64位 一块硬盘最多可以有四个主分区其中一个主分区可以用一个扩展分区替换,在这个扩展分区中 ...
- Android--------Java接口回调
>###回调说明 回调说明: 1.class A,class B 2.class A 实现接口callback 3.class B拥有一个参数为c ...
- iconv编码转换指令
看到一个不错的指令iconv,可以对文件编码进行转换,记录如下: iconv --list 列出所有支持转换的编码 icon -f code1 -t code2 filename -o newfile ...
- linux下python多版本共存
为何要安装python,linux下不是已经集成了python吗? 大多数linux系统都集成了python,但是他们的版本太低了.不能满足我们的需求,尤其是好多系统居然仍停留在 python2.6. ...
- Orchard开源ASP.NET MVC CMS简介
项目简介: Orchard CMS 是一个免费的开放源代码内容管理系统,让用户可在 Microsoft ASP.NET MVC 平台上快速创建网站.它基于灵活的扩展性框架构建,使开发人员和定制人员可通 ...
- Ubunu下安装Docker
安装Docker步骤如下: sudo apt-get update sudo apt-get install apt-transport-https sudo apt-key adv --keyser ...