1- #include < iostream>
2- #include < queue>
1+ #include < iostream>
2+ #include < cstring>
3+ #include < queue>
34using namespace std ;
4-
5- const int board_size = 4 ;
6- const int direction_num = 4 ;
7- struct Piece
5+ int N, K; // 农民位置 和 牛的位置
6+ const int MAXN = 10000 ;
7+ int visited[MAXN + 10 ]; // 判重标记
8+ struct Step
89{
9- int status; // 状态值
10- int steps; // 步数
11- Piece (int st , int step):status(st), steps(step) {}
10+ int x; // 当前位置
11+ int steps; // 到达x所需要的步数
12+ Step (int xx , int ss) : x(xx), steps(ss) {}
1213};
13- int direction[direction_num][2 ] = {
14- {-1 ,0 }, {0 ,1 },{1 ,0 },{0 ,-1 }
15- };
16- int pos[board_size *board_size]; // 16种反转可能性
17- bool marker[1 <<(board_size*board_size)];
18-
19- bool inBoard (int x, int y)
20- {
21- if (x>=0 && x<board_size && y>=0 && y<board_size)
22- return true ;
23- else
24- return false ;
25- }
26- void FlipInitialize ()
27- {
28- for (int i = 0 ; i < board_size; i++)
29- {
30- for (int j = 0 ; j< board_size; j++)
31- {
32- // i*size+j 即为编号
33- int value = 1 << (i * board_size + j);
34- for (int k = 0 ; k<direction_num; k++)
35- {
36- int next_x = i + direction[k][0 ];
37- int next_y = j + direction[k][1 ];
38- if (inBoard (next_x, next_y))
39- value += 1 << (next_x *board_size + next_y);
40- }
41- pos[i * board_size + j] = value;
42- }
43- }
44-
45- }
46- int BFS (int value)
14+ queue<Step> open_table; // 队列,即open表
15+ int main ()
4716{
48- queue<Piece> q ;
49- Piece s = Piece (value , 0 );
50- q .push (s );
51- marker[s. status ] = true ;
52- while (!q .empty ())
17+ cin >> N >> K ;
18+ memset (visited , 0 , sizeof (visited) );
19+ open_table .push (Step (N, 0 ) );
20+ visited[N ] = 1 ;
21+ while (!open_table .empty ())
5322 {
54- Piece cur = q.front ();
55- q.pop ();
56- // 盘面全黑或者全白(2^16 -1)时结束,并返回步数
57- if (cur.status == 0 || cur.status == (1 <<(board_size*board_size))-1 )
23+ Step s = open_table.front ();
24+ if (s.x == K)
5825 {
59- return cur.steps ;
26+ // 找到目标
27+ cout << s.steps << endl;
28+ return 0 ;
6029 }
61- // 搜索16个位置
62- for (int i = 0 ; i< board_size*board_size; ++i)
30+ else
6331 {
64- // 通过异或运算得到翻转后的状态
65- Piece next = Piece (cur.status ^ pos[i], cur.steps +1 );
66- if (!marker[next.status ])
32+ if (s.x - 1 >= 0 && !visited[s.x - 1 ])
6733 {
68- q.push (next);
69- marker[next.status ] = true ;
34+ // 向左走一步
35+ open_table.push (Step (s.x - 1 , s.steps + 1 ));
36+ visited[s.x - 1 ] = 1 ;
7037 }
71-
38+ if (s.x + 1 <= MAXN && !visited[s.x + 1 ])
39+ {
40+ open_table.push (Step (s.x + 1 , s.steps + 1 ));
41+ visited[s.x + 1 ] = 1 ;
42+ }
43+ if (s.x * 2 <= MAXN && !visited[s.x * 2 ])
44+ {
45+ open_table.push (Step (s.x * 2 , s.steps + 1 ));
46+ visited[s.x * 2 ];
47+ }
48+ open_table.pop (); // z依据当前点搜索完后,弹出
7249 }
7350 }
74- return -1 ; // 无法到达目标状态 返回-1
75- }
76- int main ()
77- {
78- FlipInitialize ();
79- char str[5 ];
80- int value = 0 ;
81- for (int i=0 ; i<board_size; i++)
82- {
83- cin>>str;
84- for (int j=0 ; j<board_size; j++)
85- {
86- if (str[j]== ' w' )
87- value += 1 <<(i*board_size + j);
88- // 加上 1<<(编号) 即可将此位置设置为1
89- }
90- }
91- int ans = BFS (value);
92- if (ans >= 0 )
93- cout<<ans<<endl;
94- else
95- {
96- cout<<" Impossible" <<endl;
97- }
9851 return 0 ;
9952}
0 commit comments