Jurassic Remains

Paleontologists in Siberia have recently found a number of fragments of Jurassic period dinosaur skeleton. The paleontologists have decided to forward them to the paleontology museum. Unfortunately, the dinosaur was so huge, that there was no box that the fragments would fit into. Therefore it was decided to split the skeleton fragments into separate bones and forward them to the museum where they would be reassembled. To make reassembling easier, the joints where the bones were detached from each other were marked with special labels. Meanwhile, after packing the fragments, the new bones were found and it was decided to send them together with the main fragments. So the new bones were added to the package and it was sent to the museum.

However, when the package arrived to the museum some problems have shown up. First of all, not all labels marking the joints were distinct. That is, labels with letters `A' to `Z' were used, and each two joints that had to be connected were marked with the same letter, but there could be several pairs of joints marked with the same letter.

Moreover, the same type of labels was used to make some marks on the new bones added to the box. Therefore, there could be bones with marked joints that need not be connected to the other bones. The problem is slightly alleviated by the fact that each bone has at most one joint marked with some particular letter.

Your task is to help the museum workers to restore some possible dinosaur skeleton fragments. That is, you have to find such set of bones, that they can be connected to each other, so that the following conditions are true:

  • If some joint is connected to the other joint, they are marked with the same label.
  • For each bone from the set each joint marked with some label is connected to some other joint.
  • The number of bones used is maximal possible.

Note that two bones may be connected using several joints.

Input 

Input consists of several datasets. The first line of each dataset contains N - the number of bones (1N24). Next N lines contain bones descriptions: each line contains a non-empty sequence of different capital letters, representing labels marking the joints of the corresponding bone.

Output 

For each dataset, on the first line of the output print L - the maximal possible number of bones that could be used to reassemble skeleton fragments. After that output L integer numbers in ascending order - the bones to be used. Bones are numbered starting from one, as they are given in the input file.

Sample Input 

6
ABD
EG
GE
ABE
AC
BCD

Sample Output 

5
1 2 3 5 6 题目大意:侏罗纪。给定n个大写字母组成的字符串。选择尽量多的串,使得每个大写字母都能出现偶数次。 分析:在一个字符串中,每个字符出现的次数无关紧要,重要的是这些次数的奇偶性,因此想到用一个二进制的位表示一个字母(1表示出现奇数次,0表示出现偶数次)。
  样例写成二进制后为
    A B C D E F G H
    1 1 0 1 0 0 0 0 A B D
    0 0 0 0 1 0 1 0 E G
    0 0 0 0 1 0 1 0 G E
    1 1 0 0 1 0 0 0 A B E
    1 0 1 0 0 0 0 0 A C
    0 1 1 1 0 0 0 0 B C D     问题转化为求尽量多的数,使得它们的xor值为0
  穷举法会超时。注意到xor值为0的两个整数必须完全相等,可以把字符串分成两个部分:首先计算前n/2个字符串所能得到的所有xor值,并将其保存到一个映射S(xor值 前n/2个字符串的一个子集)中;然后枚举后n/2个字符串所能得到的所有xor值,并每次都在S中查找。
  如果映射用STL的map实现,总时间复杂度为O(2n/2logn),这种方法称为中途相遇法。 代码如下:
 #include<cstdio>
#include<map>
using namespace std; const int maxn = ;
map<int,int> table; int bitcount(int x) { return x == ? : bitcount(x/) + (x&); } int main() {
int n, A[maxn];
char s[]; while(scanf("%d", &n) == && n) {
// 输入并计算每个字符串对应的位向量
for(int i = ; i < n; i++) {
scanf("%s", s);
A[i] = ;
for(int j = ; s[j] != '\0'; j++) A[i] ^= (<<(s[j]-'A'));
}
// 计算前n1个元素的所有子集的xor值
// table[x]保存的是xor值为x的,bitcount尽量大的子集
table.clear();
int n1 = n/, n2 = n-n1;
for(int i = ; i < (<<n1); i++) {
int x = ;
for(int j = ; j < n1; j++) if(i & (<<j)) x ^= A[j];
if(!table.count(x) || bitcount(table[x]) < bitcount(i)) table[x] = i;
}
// 枚举后n2个元素的所有子集,并在table中查找
int ans = ;
for(int i = ; i < (<<n2); i++) {
int x = ;
for(int j = ; j < n2; j++) if(i & (<<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 = ; i < n; i++) if(ans & (<<i)) printf("%d ", i+);
printf("\n");
}
return ;
}
 

LA 2965 Jurassic Remains (中途相遇法)的更多相关文章

  1. UVa LA 2965 - Jurassic Remains 中间相遇,状态简化 难度: 2

    题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...

  2. LA 2965 Jurassic Remains

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

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

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

  4. LA 2965 中途相遇法

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

  5. UVALive - 2965 Jurassic Remains (LA)

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

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

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

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

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

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

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

  9. 高效算法——J 中途相遇法,求和

    ---恢复内容开始--- J - 中途相遇法 Time Limit:9000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Su ...

随机推荐

  1. SpringMVC(一)

    开始学习SpringMVC了,就写下每次学习的内容,以及自己的理解.方便以后回顾知道自己哪里好哪里不好~~~ 一.目录 1.主目录如此: 2.target目录 二.文件 1.主要用到的几个文件夹(如主 ...

  2. 微软.NET各子技术领域的应用前景

    从2002年微软发布.NET 1.0,其间历经了8年的发展,再到.NET 4.0,其已经成为一个庞大而复杂的软件开发与运行平台,架构日益复杂,应用领域也在不断地扩展,包容了“一堆”的子技术领域. 在. ...

  3. ios开发——实战OC篇&FMDB详解

    FMDB详解 前一篇文章中我们介绍的SQLite的使用,在iOS中原生的SQLite API在使用上相当不友好. 于是,就出现了一系列将SQLite API进行封装的库,例如FMDB.Plausibl ...

  4. [原创]VS2013 EF6连接MySql需要几步?

    精简的美丽...... 1.安装mysql server下载地址 http://cdn.mysql.com/Downloads/MySQL-5.6/mysql-5.6.21-winx64.zip注意: ...

  5. careercup-中等难度 17.11

    17.11 给定rand5(),实现一个方法rand7().也即,给定一个产生0到4(含)随机数的方法,编写一个产生0到6(含)随机数的方法. 解法: 这个函数要正确实现,则返回0到6之间的值,每个值 ...

  6. [Effective C++ --018]让接口容易被正确使用,不易被误用

    □第一节 什么是接口?什么是接口?百度百科的解释:两个不同系统(或子程序)交接并通过它彼此作用的部分.接口的概念贯穿于整个软件开发过程中,本文讨论的接口概念仅局限于以C++实现的class,funct ...

  7. 10个android开源项目

    http://www.51testing.com/?uid-116228-action-viewspace-itemid-244285 1.Android团队提供的示例项目 如果不是从学习Androi ...

  8. Android View的绘制机制流程深入详解(三)

    本系列文章主要着重深入介绍Android View的绘制机制及流程,第三篇主要介绍并分析视图状态以及重绘流程,首先剖析了 视图的几种状态,然后在深入分析视图的重绘机制流程. 真题园网:http://w ...

  9. Android_Dialog

    layout.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xml ...

  10. nginx 安装部署

    1. 安装passenger:sudo gem install passenger 2. 找到passenger的安装目录,一般是 cd  /var/lib/gems/2.0.0/gems/passe ...