zoukankan      html  css  js  c++  java
  • Uva 1326 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 (1$ \le$N$ \le$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 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
    ---------

    求尽量多的数,使得他们异或为0。

    直接穷举,时间复杂度O(2^n);

    注意到,异或为0的两个整数一定相等,所以可将数分为两个部分,首先记录前n/2个数所有异或值保存在map中。

    然后枚举后n/2个数的异或值,并在map中查找。时间复杂度为O(2^(n/2)logn)即O(1.44^nlogn),这种方法称为中途相遇法。

    ---------

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    
    using namespace std;
    
    const int maxn=24;
    map<int,int>mp;
    
    int bitcount(int x)
    {
        return x==0?0:(bitcount(x>>1)+(x&1));
    }
    
    int main()
    {
        int n,a[maxn];
        char s[1111];
        while (~scanf("%d",&n))
        {
            if (n==0) break;
            getchar();
            for (int i=0;i<n;i++)
            {
                scanf("%s",s);
                a[i]=0;
                for (int j=0;s[j];j++)
                {
                    a[i]^=(1<<(s[j]-'A'));
                }
            }
            mp.clear();
            int n1=n/2,n2=n-n1;
            for (int i=0;i<(1<<n1);i++)
            {
                int x=0;
                for (int j=0;j<n1;j++)
                {
                    if (i&(1<<j)) x^=a[j];
                }
                if (!mp.count(x)||bitcount(mp[x])<bitcount(i))
                    mp[x]=i;
            }
            int ans=0;
            for (int i=0;i<(1<<n2);i++)
            {
                int x=0;
                for (int j=0;j<n2;j++)
                {
                    if (i&(1<<j)) x^=a[n1+j];
                }
                if (mp.count(x)&&bitcount(ans)<bitcount(mp[x])+bitcount(i))
                    ans=(i<<n1)^mp[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;
    }
    





  • 相关阅读:
    转:选择好友的下拉控件(类型开心网的)
    转:Silverlight样式写法
    转:构建无坚不摧的网站环境—NLB+Cluster(一)
    SQL2005 Collate问题
    转:写HTML邮件的建议及规范
    转:extjs里的fieldset不居中的解决办法(记录)
    转:大规模网站架构技术原理透析
    转:关于大型asp.net应用系统的架构架构的选择
    转:构建无坚不摧的网站环境——NLB+Cluster(二)
    ASP.NET MVC 2.0在WinXP IIS6下的部署
  • 原文地址:https://www.cnblogs.com/cyendra/p/3226353.html
Copyright © 2011-2022 走看看