双向BFS
棋盘上有四个棋子,给你两个状态,问可否8步内将一个状态转移到另一个状态。双向BFS。
偶这题写了一晚加一个下午,一开始兴致勃勃地单向BFS,当TLE后才发现状态总数估计错误了,应该是(4*4)^8。以后这样的错误要避免撒~~~~
然后判重时用 int mark[8][8][8][8][8][8][8][8],一交,超内存了,再次悲剧。其实这样的话内存耗费是(8^8)*4/1024 = 65536K,明显要超的~~~~~
#include <iostream> #include <queue> #include <algorithm> using namespace std; struct Node { int x, y; }; struct Status { Node nd[4]; int deep;}; char mark[8][8][8][8][8][8][8][8]; int dir[4][2] = { 0, -1, -1, 0, 0, 1, 1, 0 }; Status _s; queue<Status> Q1, Q2; bool cmp( Node n1, Node n2 ) { if( n1.x != n2.x ) return n1.x < n2.x; else return n1.y < n2.y; } void Mark( Status s1, int v ) { v --; mark[s1.nd[0].x][s1.nd[0].y][s1.nd[1].x][s1.nd[1].y][s1.nd[2].x][s1.nd[2].y][s1.nd[3].x][s1.nd[3].y] |= (1<<v); } void init() { int i; memset( mark, 0, sizeof(mark) ); for( i=1; i<4; ++i ) { scanf( "%d %d", &_s.nd[i].x, &_s.nd[i].y ); } for( i=0; i<4; ++i ) { _s.nd[i].x --; _s.nd[i].y --; } sort( _s.nd, _s.nd+4, cmp ); while( !Q1.empty() ) Q1.pop(); while( !Q2.empty() ) Q2.pop(); _s.deep = 0; Q1.push( _s ); Mark( _s, 1 ); for( i=0; i<4; ++i ) { scanf( "%d %d", &_s.nd[i].x, &_s.nd[i].y ); _s.nd[i].x --; _s.nd[i].y --; } sort( _s.nd, _s.nd+4, cmp ); _s.deep = 0; Q2.push( _s ); Mark( _s, 2 ); } bool occupy( Status _p, int v, Status _q ) { for( int i=0; i<4; ++i ) { if( _p.nd[v].x == _q.nd[i].x && _p.nd[v].y == _q.nd[i].y ) return 1; } return 0; } bool isVisited( Status s1, int v ) { v --; if( mark[s1.nd[0].x][s1.nd[0].y][s1.nd[1].x][s1.nd[1].y][s1.nd[2].x][s1.nd[2].y][s1.nd[3].x][s1.nd[3].y] &(1<<v) ) return 1; return 0; } bool solve() { int i, j; Status _p, _q; while( !Q1.empty() || !Q2.empty() ) { if( !Q1.empty() ) { _p = Q1.front(); Q1.pop(); if( _p.deep >= 4 ) continue; for( i=0; i<4; ++i ) { for( j=0; j<4; ++j ) { _q = _p; _q.deep ++; _q.nd[i].x += dir[j][0]; _q.nd[i].y += dir[j][1]; if( _q.nd[i].x < 0 || _q.nd[i].y < 0 || _q.nd[i].x >= 8 || _q.nd[i].y >= 8) continue; if( occupy(_q, i, _p) ) { _q.nd[i].x += dir[j][0]; _q.nd[i].y += dir[j][1]; } if( _q.nd[i].x < 0 || _q.nd[i].y < 0 || _q.nd[i].x >= 8 || _q.nd[i].y >= 8 || occupy(_q, i, _p)) continue; sort( _q.nd, _q.nd+4, cmp ); if( isVisited( _q, 1 ) ) continue; if( isVisited( _q, 2 ) ) return 1; Q1.push( _q ); Mark( _q, 1 ); } } } if( !Q2.empty() ) { _p = Q2.front(); Q2.pop(); if( _p.deep >= 4 ) continue; for( i=0; i<4; ++i ) { for( j=0; j<4; ++j ) { _q = _p; _q.deep ++; _q.nd[i].x += dir[j][0]; _q.nd[i].y += dir[j][1]; if( _q.nd[i].x < 0 || _q.nd[i].y < 0 || _q.nd[i].x >= 8 || _q.nd[i].y >= 8) continue; if( occupy(_q, i, _p) ) { _q.nd[i].x += dir[j][0]; _q.nd[i].y += dir[j][1]; } if( _q.nd[i].x < 0 || _q.nd[i].y < 0 || _q.nd[i].x >= 8 || _q.nd[i].y >= 8 || occupy(_q, i, _p) ) continue; sort( _q.nd, _q.nd+4, cmp ); if( isVisited( _q, 2 ) ) continue; if( isVisited( _q, 1 ) ) return 1; Q2.push( _q ); Mark( _q, 2 ); } } } } return 0; } int main() { // freopen( "c:/aaa.txt", "r", stdin ); while( scanf("%d %d", &_s.nd[0].x, &_s.nd[0].y ) == 2 ) { init(); solve() ? puts( "YES" ) : puts( "NO" ); } return 0; }
.