这题跟POJ1753 flip game 思想一样。。唯一不同得是这题要保存方案。
用c++一直超时,g++500多ms.
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <stdio.h> #include <string.h> #include <iostream> #include <queue> #include <stack> using namespace std; int visit[70000]; char mp[1100]; struct node { int state; int num; }p; struct pnode { int x, y; }px[70000]; int path[70000]; int STATE; int flip_num[16] = {63624,62532,61986,61713,36744,20292,12066,7953,35064, 17652,8946,4593,34959,17487, 8751, 4383}; void print( int x ) { stack<int>qx; while( x != STATE ) { qx.push(x); x = path[x]; //printf("%d %d\n", px[x].x + 1, px[x].y + 1); } while( !qx.empty( ) ) { int t = qx.top(); qx.pop( ); printf("%d %d\n", px[t].x + 1, px[t].y + 1); } } void print1( int x ) { if( x != STATE ) { print1( path[x] ); printf("%d %d\n", px[x].x + 1, px[x].y + 1); } } void bfs( ) { int flag = 0; node pp; queue<node>q; q.push(p); visit[p.state] = 1; while( !q.empty()) { p = q.front(); q.pop(); pp.state = p.state; for( int i = 0; i < 16; i++) { p.state = pp.state; //p.state = p.state ^ ( flip_num[15-i] ); 500多ms.. int row = i / 4; int col = i - row * 4; p.state = p.state ^ ( 1 << i ); for( int j = 0; j < 4; j++) { p.state = p.state ^ (1 << (row * 4 + j ) ); p.state = p.state ^ (1 << (4 * j + col ) ); } if( p.state == 0 ) { cout<<p.num+1<<endl; px[p.state].x = row; px[p.state].y = col; path[p.state] = pp.state; print1( 0 ); return; } if( visit[p.state] == 0 ) { px[p.state].x = row; px[p.state].y = col; path[p.state] = pp.state; node temp; temp.state = p.state; temp.num = p.num + 1; visit[p.state] = 1; q.push(temp); } } } } int main( ) { p.state = 0; p.num = 0; memset(visit, 0, sizeof(visit)); for(int i = 0; i < 16; i++) { cin>>mp[i]; if( mp[i] == '+') p.state += (1<<i); } STATE = p.state; bfs( ); return 0; }