例题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的更多相关文章

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

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

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

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

  3. UVALive - 2965 Jurassic Remains (LA)

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

  4. 【中途相遇法】【STL】BAPC2014 K Key to Knowledge (Codeforces GYM 100526)

    题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show& ...

  5. 【UVALive2965】Jurassic Remains

    题意 题意给定n个大写字母组成的字符串,选择尽量多的串,使得每个大写字母都能出现偶数次.n<=24,每个字符串中每个字母最多出现一次. 分析 这是训练指南上的一道中途相遇法的简单题,但是好像也能 ...

  6. LA 2965 中途相遇法

    题目链接:https://vjudge.net/problem/UVALive-2965 题意: 有很多字符串(24),选出一些字符串,要求这些字符串的字母都是偶数次: 分析: 暴力2^24也很大了, ...

  7. 中途相遇法 解决 超大背包问题 pack

    Description [题目描述] 蛤布斯有n个物品和一个大小为m的背包,每个物品有大小和价值,它希望你帮它求出背包里最多能放下多少价值的物品. [输入数据] 第一行两个整数n,m.接下来n行每行两 ...

  8. uva 6757 Cup of Cowards(中途相遇法,貌似)

    uva 6757 Cup of CowardsCup of Cowards (CoC) is a role playing game that has 5 different characters (M ...

  9. HDU 5936 Difference 【中途相遇法】(2016年中国大学生程序设计竞赛(杭州))

    Difference Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

随机推荐

  1. LabVIEW新手5大错误

    虽然NI LabVIEW软件长期以来一直帮助工程师和科学家们快速开发功能测量和控制应用,但不是所有的新用户都会遵循LabVIEW编程的最佳方法. LabVIEW图形化编程比较独特,因为只需看一眼用户的 ...

  2. java.util.concurrent.ExecutionException

    java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start com ...

  3. windows-JDK环境变量设置

    JAVA_HOME=C:\Program Files\Java\jdk1.6.0_43;CLASS_PATH=.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar;p ...

  4. php + apache + mysql

    http://archive.apache.org/dist/httpd/binaries/win32/   Apache msi 下载地址

  5. Android-----------国际化多国语言文件夹命名汇总

    *如果不区分地区,则不加后面的-rxx内容 Arabic, Egypt (ar_rEG) —————————–阿拉伯语,埃及      Arabic, Israel (ar_rIL) ———————— ...

  6. PHP学习笔记三十七【http】

    <?php print_r($_SERVER); //$_SERVER预编译变量[数组]输出请求报文,注意大小写 echo "<br/>"; foreach($_ ...

  7. Could not load file or assembly 'Oracle.DataAccess' or one of its dependencies. An attempt was made to load a program with an incorrect format.

    I have installed a Web application on IIS 7.0 windows server 2008 R2 64 bit OS I am refering a oracl ...

  8. Lucene学习总结之二:Lucene的总体架构

    Lucene总的来说是: 一个高效的,可扩展的,全文检索库. 全部用Java实现,无须配置. 仅支持纯文本文件的索引(Indexing)和搜索(Search). 不负责由其他格式的文件抽取纯文本文件, ...

  9. DOM2定位与高宽类属性专题学习【DOM专题学习系列(一)】

    网页可见区域宽: document.body.clientWidth;网页可见区域高: document.body.clientHeight;网页可见区域宽: document.body.offset ...

  10. HTML5简单入门系列(三)

    前言 本篇介绍HTML5支持的Web存储(Web Storage)和HTML 5 应用程序缓存. 客户端存储数据介绍 HTML5 提供了两种在客户端存储数据的新方法: localStorage - 没 ...