因为牌子的种类最多有2^16个,所以搜索一下就可以得到答案。
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> using namespace std; struct T { int n; int c; }; queue<T> q; int tar,len,le,v[68000],E[120]; char str[20]="11001"; T tp,tp2; int f(int len,char *str) { int i,cnt; cnt=0; for (i=len-1; i>=0; i--) { cnt+=(str[i]=='1')?pow(2,len-i-1):0; } return cnt; } char *g(int len,int n) { int i; for (i=len-1; i>=0; i--) { if (n>=pow(2,i)) { str[len-i-1]='1'; n-=pow(2,i); } else str[len-i-1]='0'; } str[len]='\0'; return str; } int judge(int a,int b) { int cnt,t,i; cnt=0; for (i=len-1; i>=0; i--) { t=pow(2,i); if (a >= t && b >= t) { a-=t; b-=t; } else if (a >= t && b < t) { a-=t; cnt++; } else if (a < t && b >= t) { b-=t; cnt++; } } return cnt; } int main() { int i,j,ans,degree; scanf("%d%d",&len,&le); getchar(); scanf("%s",str); tar=f(len,str); while (!q.empty()) q.pop(); memset(v,0,sizeof(v)); for (i=0; i<le; i++) { scanf("%s",str); E[i]=f(len,str); tp.n=E[i]; tp.c=0; q.push(tp); } while (!q.empty()) { tp=q.front(); q.pop(); for (i=0; i<le; i++) { tp2.n=tp.n^E[i]; if (v[tp2.n] == 0) { v[tp2.n]=tp.c+1; tp2.c=tp.c+1; q.push(tp2); } else if (v[tp2.n] != 0 && tp.c+1 < v[tp2.n]) { v[tp2.n]=tp.c+1; q.push(tp2); } } } if (v[tar] != 0) { printf("%d\n%s\n",v[tar],g(len,tar)); return 0; } degree=-1; ans=-1; for (i=0; i<68000; i++) { if (v[i] != 0) { j=judge(tar,i); if (degree == -1 || degree > j) { ans=i; degree=j; } else if (degree == j) { if (v[ans] > v[i]) { ans=i; } } } } printf("%d\n%s\n",v[ans],g(len,ans)); }