Uva 1326 Jurassic Remains

Uva 1326

Sample Input

1

ABC

6

ABD

EG

GE

ABE

AC

BCD

Sample Output

0

5

1 2 3 5 6

给出n个字符串,每个字符串都是由大写字母组成,要求你选择尽可能多的字符串结合成一个字符串,而且这个字符串的每个字母出现的次数都为偶数

这道题可以直接使用暴搜的方法做,但其中的难点在于如何判断,应该使用二进制表示,每个数开始都为0,那么这个数默认它有26位,每一位代表一个字母,出现偶数次即为0(出现0次也算),出现奇数次就为1,那么一个字符串就可以使用一个int型的数来表示,0代表还没开始选,选择这个数就^上相对应的数,最终那个数为0代表可行(每个数都出现偶数次或者没出现过,表现为26位每一位都为0),如果不为0则说明肯定有一位上对应的字母出现了奇数次。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=30;
int a[maxn];
int vis[maxn];
char str[maxn];
int n;

int dfs(int cur,int cnt,int dc)
{
    if(cur==n)
    {
        if(dc==0) return cnt;
        return -1;
    }
    else
    {
        vis[cur]=1;
        int ans=dfs(cur+1,cnt+1,dc^a[cur]);
        if(ans!=-1) return ans;
        vis[cur]=0;
        ans=dfs(cur+1,cnt,dc);
        if(ans!=-1) return ans;
    }
}

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
     memset(a,0,sizeof(a));
     for(int i=0;i<n;i++)
     {
         scanf("%s",str);
         for(int j=0;j<strlen(str);j++)
         {
             a[i]^=(1<<(str[j]-'A'));
         }
     }
         int ans;
         ans=dfs(0,0,0);
         printf("%d
",ans);
         int first=1;
         for(int i=0;i<n;i++)
         {
             if(!vis[i]) continue;
             if(first) first=0;
             else      printf(" ");
             printf("%d",i+1);
         }
         printf("
");
     }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zsyacm666666/p/4921139.html