UVA 1326 - Jurassic Remains(技巧枚举+位运算)
2014-02-07 06:06
399 查看
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.
N
24).
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.
numbers in ascending order - the bones to be used. Bones are numbered starting from one, as they are given in the input file.
题意:说白了就是找最多字符串使得所有字符出现次数为偶数次。
思路:枚举一半的字符串取不取,可以用位运算表示,然后对于每个字母奇数为1偶数为0,然后在去枚举另一半,如果另一半出现一个状态之前出现过,就代表可以组合,因为相同状态奇数+奇数,偶数+偶数,最终得到都是偶数。
代码:
#include <stdio.h>
#include <string.h>
#include <map>
using namespace std;
const int N = 30;
int n, state
;
char str
;
map<int, int> vis;
int bitcount(int state) {
return state ? bitcount(state/2) + (state&1) : 0;
}
void init() {
vis.clear();
memset(state, 0, sizeof(state));
for (int i = 0; i < n; i++) {
scanf("%s", str);
for (int j = 0; j < strlen(str); j++)
state[i] = (state[i]^(1<<(str[j] - 'A')));
}
}
void solve() {
int i, j, n1 = n / 2, n2 = n - n1, bit1 = 0, bit2 = 0;
for (i = 0; i < (1<<n1); i++) {
int s = 0;
for (j = 0; j < n1; j++) {
if (i&(1<<j)) {
s = (s^state[j]);
}
}
if (bitcount(i) > bitcount(vis[s]))
vis[s] = i;
}
int ans = 0;
for (i = 0; i < (1<<n2); i++) {
int s = 0;
for (j = 0; j < n2; j++) {
if (i&(1<<j)) {
s = (s^state[j + n1]);
}
}
if (vis[s] && ans < bitcount(i) + bitcount(vis[s])) {
ans = bitcount(i) + bitcount(vis[s]);
bit1 = vis[s]; bit2 = i;
}
}
int bo = 0;
printf("%d\n", ans);
for (i = 0; i < n1; i++)
if (bit1&(1<<i)) {
if (bo++) printf(" ");
printf("%d", i + 1);
}
for (i = 0; i < n2; i++)
if (bit2&(1<<i)) {
if (bo++) printf(" ");
printf("%d", i + 1 + n1);
}
printf("\n");
}
int main() {
while (~scanf("%d", &n)) {
init();
solve();
}
return 0;
}
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 (1N
24).
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 integernumbers 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
题意:说白了就是找最多字符串使得所有字符出现次数为偶数次。
思路:枚举一半的字符串取不取,可以用位运算表示,然后对于每个字母奇数为1偶数为0,然后在去枚举另一半,如果另一半出现一个状态之前出现过,就代表可以组合,因为相同状态奇数+奇数,偶数+偶数,最终得到都是偶数。
代码:
#include <stdio.h>
#include <string.h>
#include <map>
using namespace std;
const int N = 30;
int n, state
;
char str
;
map<int, int> vis;
int bitcount(int state) {
return state ? bitcount(state/2) + (state&1) : 0;
}
void init() {
vis.clear();
memset(state, 0, sizeof(state));
for (int i = 0; i < n; i++) {
scanf("%s", str);
for (int j = 0; j < strlen(str); j++)
state[i] = (state[i]^(1<<(str[j] - 'A')));
}
}
void solve() {
int i, j, n1 = n / 2, n2 = n - n1, bit1 = 0, bit2 = 0;
for (i = 0; i < (1<<n1); i++) {
int s = 0;
for (j = 0; j < n1; j++) {
if (i&(1<<j)) {
s = (s^state[j]);
}
}
if (bitcount(i) > bitcount(vis[s]))
vis[s] = i;
}
int ans = 0;
for (i = 0; i < (1<<n2); i++) {
int s = 0;
for (j = 0; j < n2; j++) {
if (i&(1<<j)) {
s = (s^state[j + n1]);
}
}
if (vis[s] && ans < bitcount(i) + bitcount(vis[s])) {
ans = bitcount(i) + bitcount(vis[s]);
bit1 = vis[s]; bit2 = i;
}
}
int bo = 0;
printf("%d\n", ans);
for (i = 0; i < n1; i++)
if (bit1&(1<<i)) {
if (bo++) printf(" ");
printf("%d", i + 1);
}
for (i = 0; i < n2; i++)
if (bit2&(1<<i)) {
if (bo++) printf(" ");
printf("%d", i + 1 + n1);
}
printf("\n");
}
int main() {
while (~scanf("%d", &n)) {
init();
solve();
}
return 0;
}
相关文章推荐
- uva 1326 - Jurassic Remains(暴力+位运算+中间相遇法)
- UVa 1326 - Jurassic Remains(枚举子集+中途相遇法)
- UVA - 1326 Jurassic Remains (折半搜索)
- Uva 1326 - Jurassic Remains 中途相遇法
- Jurassic Remains(LA 2965)位运算+枚举
- uva 1326 - Jurassic Remains
- uva1326 - Jurassic Remains 中途相遇法
- UVA 1326 Jurassic Remains
- UVa 1326 - Jurassic Remains
- UVa1326--Jurassic Remains(折半搜索)
- UVA 1326 Jurassic Remains
- UVa 1326 Jurassic Remains 解题报告(Meet-in-the-Middle)
- UVA 1326 Jurassic Remains 中途相遇法
- Uva 1326 - Jurassic Remains 中途相遇法
- UVA 1326 B - Jurassic Remains——暴力
- (UVA - 10976)Fractions Again?!(技巧,暴力枚举)
- [UVA-1326] (暴力+位运算+中间相遇法)
- UVA 1326 Jurssic Remains(位运算)
- UVa 658 It's not a Bug, it's a Feature! 位运算技巧+dijkstra优先队列优化
- uvalive2965Jurassic Remains