ZOJ 2050BFS加位运算,这样节省了空间,由于4*4的空间太大状态数组存不下,看了别人的代码顿悟了!用二进制只要2^16-1=65535个数组便可存下。白色用状态1表示很色用0表示。

 1 #include<cstdio>
2 #include<cstring>
3 #include<cstdlib>
4 #include<iostream>
5 #include<queue>
6
7 using namespace std;
8
9 int dx[4] = {1, 0, -1, 0};//控制四个方向
10 int dy[4] = {0, 1, 0, -1};
11 int visit[65536];
12 char s[4][4];
13
14 typedef struct
15 {
16 int data;
17 int step;
18 }Point;
19
20 int True(int x, int y)
21 {
22 if(x>=0 && x<4 && y>=0 && y<4)
23 return 1;
24 return 0;
25 }
26
27 queue<Point>q;
28 int main()
29 {
30 int i, j, ncases, k, sate, x, y, nx, ny, flag;
31 Point Start, Target;
32
33 scanf("%d", &ncases);
34 while( ncases-- )
35 {
36 sate = 0;
37 for(i=0; i<4; i++)
38 {
39 scanf("%s", s[i]);
40 for(j=0; j<4; j++)
41 {
42 if(s[i][j] == 'b')
43 sate |= 1<<(i*4+j);//将1移到下表所在位置将其表示为1即白色
44 }
45 }
46 memset(visit, 0, sizeof(visit));
47 flag = 0;
48 Start.data = sate;
49 Start.step = 0;
50 visit[Start.data] = 1;
51 q.push(Start);
52 while( !q.empty() )
53 {
54 Point u = q.front();
55 q.pop();
56 if(u.data==0 || u.data==65535)
57 {
58 printf("%d\n", u.step);
59 flag = 1;
60 break;
61 }
62 for(k=0; k<16; k++)
63 {
64 Point v;
65 v.step = u.step + 1;
66 v.data = u.data^(1<<k);//异或运算可将数据反转相当于在原图中颜色的变化1变为0或0变为1
67 x = k/4;
68 y = k%4;
69 for(i=0; i<4; i++)
70 {
71 nx = x + dx[i];
72 ny = y + dy[i];
73 if( True(nx,ny) )
74 {
75 v.data = v.data^(1<<(nx*4+ny));//原有的数据翻转
76 }
77 }
78 if( !visit[v.data] )
79 {
80 q.push(v);
81 visit[v.data] = 1;
82 }
83 }
84 }
85 if( !flag )
86 printf("Impossible\n");
87 if( ncases )
88 printf("\n");
89 while( !q.empty() )//不要忘了加,队列一定要清空,以便下次使用时队列里为空不会发生数据的冲突
90 {
91 q.pop();
92 }
93 }
94 return 0;
95 }
posted @ 2012-03-02 23:09  zhongya  阅读(182)  评论(0编辑  收藏  举报