zoukankan      html  css  js  c++  java
  • LA2965 n个数中选出最多个数异或和为0

    intput

    n 1<=n<=24

    n串只有大写字母的字符串

    output

    选出最多个字符串且每个大写字母出现的次数为偶数

    第一行输出个数x

    第二行输出x个字符串的下标

    做法:将每个字符串转化为一个26bit数,1为奇数个大写字母,0为偶数个,则转化为找出最多个数异或和为0,直接枚举为O((2^n)*n),但只有a^a=0,所以将n个数分为两半(中途相遇法),复杂度降为O((2^(n/2))logn)

    注意:异或和左半为0和右半为0的要特判,且右半要全部判完,因为可能出现2+3<5+1

      1 #include <cstdio>
      2 #include <queue>
      3 #include <cstring>
      4 #include <iostream>
      5 #include <cstdlib>
      6 #include <algorithm>
      7 #include <vector>
      8 #include <map>
      9 #include <set>
     10 #include <ctime>
     11 #include <cmath>
     12 #define MAX 100000
     13 
     14 using namespace std;
     15 struct node
     16 {
     17     int mark,n;
     18     node operator+(const node&b)const
     19     {
     20         return (node){mark|b.mark,n+b.n};
     21     }
     22     bool operator<(const node&a)const
     23     {
     24         return n<a.n;
     25     }
     26 };
     27 int a[30],c[26],n,ch,num;
     28 char s[1000];
     29 node maxn;
     30 map<int,node>q;
     31 map<int,node>::iterator qsum;
     32 void dfs(int x,int mark,int sum,int nn)
     33 {
     34     if(x==n>>1)
     35     {
     36         q.insert(make_pair(sum,(node){mark,nn}));
     37         if(sum==0) maxn=max(maxn,(node){mark,nn});
     38         return;
     39     }
     40     sum^=a[x];
     41     nn++;
     42     mark|=1<<x;
     43     dfs(x+1,mark,sum,nn);
     44     sum^=a[x];
     45     nn--;
     46     mark&=~(1<<x);
     47     dfs(x+1,mark,sum,nn);
     48 }
     49 void find(int x,int mark,int sum,int nn)
     50 {
     51     if(x==n)
     52     {
     53         qsum=q.find(sum);
     54         if(qsum!=q.end()) maxn=max(maxn,qsum->second+(node){mark,nn});
     55         if(sum==0) maxn=max(maxn,(node){mark,nn});
     56         return;
     57     }
     58     sum^=a[x];
     59     nn++;
     60     mark|=1<<x;
     61     find(x+1,mark,sum,nn);
     62     sum^=a[x];
     63     nn--;
     64     mark&=~(1<<x);
     65     find(x+1,mark,sum,nn);
     66 }
     67 int main()
     68 {
     69     freopen("/home/user/桌面/in","r",stdin);
     70     while(scanf("%d%*c",&n)==1)
     71     {
     72         memset(a,0,sizeof(a));
     73         for(int i=0;i<n;i++)
     74         {
     75             memset(c,0,sizeof(c));
     76             scanf("%s",s);
     77             for(int j=0;s[j];j++) c[s[j]-'A']++;
     78             for(int j=0;j<26;j++) if(c[j]&1) a[i]|=1<<j;
     79         } 
     80         if(n==1)
     81         {
     82             if(a[0]) puts("0
    ");
     83             else puts("1
    1");
     84             continue;
     85         }
     86         q.clear();
     87         maxn=(node){0,0};
     88         dfs(0,0,0,0);
     89         find(n>>1,0,0,0);
     90         if(maxn.n)
     91         {
     92             printf("%d
    ",maxn.n);
     93             for(int i=0,j=0;i<n;i++)
     94             {
     95                 if(maxn.mark&(1<<i))
     96                 {
     97                     if(j) putchar(' ');
     98                     printf("%d",i+1);
     99                     j=1;
    100                 }
    101             }
    102             printf("
    ");
    103         }
    104         else puts("0
    ");
    105     }
    106     //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    循环队列和链队列的实现
    【lightoj-1026】Critical Links(桥)
    顺序栈和链栈的实现
    【51nod-1605】棋盘问题
    【51nod-1596】搬货物
    【海明码】(容易看懂)
    【lightoj-1094】树的直径(DFS)
    【lightoj-1046】Rider(BFS)
    【第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛-F】等式(因子个数)
    浅谈Vue个性化dashBoard 布局
  • 原文地址:https://www.cnblogs.com/cdyboke/p/4996773.html
Copyright © 2011-2022 走看看