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\n",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("\n"); } return 0; }