题意:
FJ给每个牛一个号码牌,牛不喜欢这个号码牌,就私自建立了1个机器用2个号码牌来生成一个新号码牌(两个输入口可以放一个号码牌并且不消耗号码牌),问最少使用的步数达到新号码(或者达到最优号码,N多关键字排序规则,一看就知道搜索)。
解法&代码
BFS,直接看代码吧。。
1 Source Code
2
3 Problem: 2133 User: yzhw
4 Memory: 660K Time: 0MS
5 Language: C++ Result: Accepted
6 Source Code
7 # include <cstdio>
8 # include <cstring>
9 # include <stack>
10 # include <cstdlib>
11 using namespace std;
12 int used[1<<16];
13 int q[1<<16],s=0,e=-1;
14 int toInt(char *str)
15 {
16 int res=0;
17 for(int i=0;str[i]!='\0';i++)
18 res=res*2+str[i]-48;
19 return res;
20 }
21
22 void print(int top,int b)
23 {
24 stack<int> ans;
25 for(int i=0;i<b;i++)
26 {
27 ans.push(top%2);
28 top/=2;
29 }
30 while(!ans.empty())
31 {
32 printf("%d",ans.top());
33 ans.pop();
34 }
35 printf("\n");
36 }
37 int diff(int target,int code,int b)
38 {
39 int ans=0;
40 for(int i=0;i<b;i++)
41 {
42 ans+=(target%2!=code%2);
43 target/=2;
44 code/=2;
45 }
46 return ans;
47 }
48 int main()
49 {
50 // freopen("ans.txt","w",stdout);
51 // int pre[1<<16][2];
52 memset(used,0,sizeof(used));
53 int b,ee;
54 scanf("%d%d",&b,&ee);
55 char str[20];
56 scanf("%s",str);
57 int target=toInt(str);
58 for(int i=0;i<ee;i++)
59 {
60 scanf("%s",str);
61 q[++e]=toInt(str);
62 }
63 while(s<=e)
64 {
65 int top=q[s++];
66 //print(top,b);
67 // printf("%d %d %d %d\n",top,pre[top][0],pre[top][1],used[top]);
68 //system("pause");
69 if(top==target&&used[top])
70 {
71 printf("%d\n",used[top]);
72 print(top,b);
73 //system("pause");
74 return 0;
75 }
76 for(int i=0;i<ee;i++)
77 if(!used[top^q[i]])
78 used[top^q[i]]=used[top]+1,q[++e]=(top^q[i]);
79 }
80 int bestcode,bestdiff=0xfffffff,beststep;
81 for(int i=0;i<(1<<b);i++)
82 if(used[i]&&(diff(i,target,b)<bestdiff||diff(i,target,b)==bestdiff&&used[i]<beststep||diff(i,target,b)==bestdiff&&used[i]==beststep&&i<bestcode))
83 bestcode=i,bestdiff=diff(i,target,b),beststep=used[i];
84 printf("%d\n",beststep);
85 print(bestcode,b);
86 //system("pause");
87 return 0;
88
89 }