双向BFS

hdoj 1401 Solitaire

棋盘上有四个棋子,给你两个状态,问可否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;
}

.

posted on 2011-03-14 16:05  CrazyAC  阅读(1933)  评论(0编辑  收藏  举报