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 ;
}
 

最新文章

  1. 基于NPOI的Excel数据导入
  2. spring面试题(2)
  3. Spring3.2.2之后不赞成使用queryForInt
  4. c#存储过程
  5. 005. C#发送邮件
  6. select @@IDENTITY
  7. 《OD学Hive》第六周20160730
  8. OpenGL超级宝典第5版&amp;&amp;缓冲区
  9. C# 制作外挂常用的API
  10. 基于anyrtc的sdk实现直播连麦互动
  11. Url Rewrite IIS 配置
  12. HttpUtil工具类
  13. jsp 之 解决mysql不是内部或外部命令问题
  14. Flask 学习 四 数据库
  15. 和逛微博、刷朋友圈一样玩转 GitHub
  16. 查看dll或lib中包含的函数
  17. 转载 Flask中客户端 - 服务器 - web应用程序 是如何处理request生成response的?
  18. spring mvc 自动生成代码
  19. Math.Round四舍六入五取偶Math.Ceiling只要有小数都加1Math.Floor总是舍去小数
  20. 【转】ubuntu 打开命令行窗口的方法

热门文章

  1. home_work--用户登陆
  2. IDF实验室-简单编程-字符统计 writeup
  3. Android开发——自动生成Android屏幕适配的dimens.xml文件
  4. MFC 学习 之 状态栏的添加
  5. OpenCV Mat 类型定义和赋值
  6. iOS开发——数据持久化Swift篇&amp;iCloud云存储
  7. android115 自定义控件
  8. [010]Try块和异常处理
  9. ADO.Net的小知识(连接数据库)二
  10. Java Web services: WS-Security with Metro--referenc