[BFS] HDU 3533

来源:互联网 发布:windows经典桌面壁纸 编辑:程序博客网 时间:2024/05/21 09:03

除了二维坐标还要再加上一个时间的维度

预先处理每个子弹在每个时间的坐标作为不能走的判断


#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <queue>#include <stack>#include <string>#include <vector>using namespace std;const int maxn = 110;int m, n, k, d; //行,列,城堡个数,总时间限制int dir[ 5 ][ 2 ] = {{0, 0}, {-1, 0}, {1, 0}, {0, 1}, {0, -1}};struct Node {        int x, y;        int tim;} cur, nex;struct castle {        int dir;        //方向        int t, v, x, y; // 发射周期,速度,坐标        void input () {                getchar ();                char d;                scanf ( "%c%d%d%d%d", &d, &t, &v, &x, &y );                switch ( d ) {                case 'N':                        dir = 1;                        break;                case 'S':                        dir = 2;                        break;                case 'E':                        dir = 3;                        break;                case 'W':                        dir = 4;                        break;                }        }} ca[ maxn ];bool bullet[ maxn ][ maxn ][ 1010 ];bool has_castle[ maxn ][ maxn ];bool path ( int x, int y ) {        if ( x >= 0 && x <= n && y >= 0 && y <= m && !has_castle[ x ][ y ] )                return true;        return false;}void set_bullet () {        memset ( bullet, false, sizeof ( bullet ) );        for ( int i = 0; i < k; ++i )                for ( int j = 0; j <= d; j += ca[ i ].t ) {                        int p = 1;                        while ( 1 ) {                                //不知道为啥这里p不是一个一个加会错.....                                int xx = ca[ i ].x + dir[ ca[ i ].dir ][ 0 ] * p;                                int yy = ca[ i ].y + dir[ ca[ i ].dir ][ 1 ] * p;                                if ( !path ( xx, yy ) )                                        break;                                if ( p % ca[ i ].v == 0 )                                        bullet[ xx ][ yy ][ j + p / ca[ i ].v ] =                                            true; //这个时间有子弹                                ++p;                        }                }}bool vis[ maxn ][ maxn ][ 1010 ];int bfs () {        memset ( vis, false, sizeof ( vis ) );        cur.x = cur.y = 0;        cur.tim = 0;        vis[ 0 ][ 0 ][ 0 ] = true;        queue<Node> q;        q.push ( cur );        while ( !q.empty () ) {                cur = q.front ();                q.pop ();                if ( cur.tim > d )                        return -1;                if ( cur.x == n && cur.y == m )                        return cur.tim;                for ( int i = 0; i < 5; ++i ) {                        nex.x = cur.x + dir[ i ][ 0 ];                        nex.y = cur.y + dir[ i ][ 1 ];                        nex.tim = cur.tim + 1;                        if ( path ( nex.x, nex.y ) && !bullet[ nex.x ][ nex.y ][ nex.tim ] &&                             !vis[ nex.x ][ nex.y ][ nex.tim ] ) {                                vis[ nex.x ][ nex.y ][ nex.tim ] = true;                                q.push ( nex );                        }                }        }        return -1;}int main () {        while ( ~scanf ( "%d%d%d%d", &n, &m, &k, &d ) ) {                memset ( has_castle, false, sizeof ( has_castle ) );                for ( int i = 0; i < k; ++i ) {                        ca[ i ].input ();                        has_castle[ ca[ i ].x ][ ca[ i ].y ] = true;                }                //预处理                set_bullet ();                int ans = bfs ();                if ( ans == -1 )                        printf ( "Bad luck!\n" );                else                        printf ( "%d\n", ans );        }}