hdu 5040 bfs + 优先队列

题意是重点,监控的范围可以走但要有箱子,会浪费时间

还有就是它所谓的范围2包含中心,深坑啊...........

按照spfa的思想宽搜,比较好写

下面是我千疮百孔的ac代码:

#include <iostream>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <algorithm>
#include <queue>
#define MAX 520
#define INF 0x3f

using namespace std;

int t,n,ex,ey;
int m[MAX][MAX][5];
int used[MAX][MAX][5];
char s[MAX][MAX];

struct Node
{
    int t,x,y,wait;
    bool operator < ( const Node& a )  const
    {
        return t > a.t;
    }
}tst,st;

int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};

int bfs ( )
{
    priority_queue<Node> q;
    memset ( used , INF , sizeof ( used ) );
    st.t = 0;
    st.wait = 0;
    q.push ( st );
    used[st.x][st.y][0] = 0;
    while ( !q.empty() )
    {
        tst = q.top();
       // cout << tst.x << " " << tst.y << endl;
        if ( s[tst.x][tst.y] == 'T' ) return tst.t;
        q.pop();
        for ( int i = 0 ; i < 4 ; i++ )
        {
            st.x = tst.x + dx[i];
            st.y = tst.y + dy[i];

            if ( m[st.x][st.y][0] == -1 ) continue;
            
            int tt = tst.t%4;
            if ( m[st.x][st.y][tt] == 2 ||
                 m[tst.x][tst.y][tt] == 2 )
                st.t = tst.t + 3;
            else st.t = tst.t + 1;
            st.wait = 0;
            if ( st.t < used[st.x][st.y][st.wait] )
            {
                q.push ( st );
                used[st.x][st.y][st.wait] = st.t;
            }
        }

        st.x = tst.x;
        st.y = tst.y;
        st.t = tst.t + 1;
        st.wait = tst.wait + 1;

        if ( st.wait <= 3 && st.t < used[st.x][st.y][st.wait] )
        {
            q.push ( st );
            used[st.x][st.y][st.wait] = st.t;
        }
    }
    return -1;
}

int main ( )
{
    scanf ( "%d" , &t );
    int c = 1;
    while ( t-- )
    {
        scanf ( "%d" , &n );
        memset ( m , -1 , sizeof ( m ) );
        for ( int i = 1 ; i <= n ; i++ )
        {
            scanf ( "%s" , s[i]+1 );
            for ( int j = 1 ; j <= n ; j++ )
            {
                if ( s[i][j] == '.' ) 
                    for ( int k = 0 ; k < 4 ; k++ )
                        m[i][j][k] = 1;
                if ( s[i][j] == 'M' )
                {
                    st.x = i , st.y = j;
                    for ( int k = 0 ; k < 4 ; k++ )
                        m[i][j][k] = 1;
                }
                if ( s[i][j] == 'T' )
                {
                    ex = i , ey = j;
                    for ( int k = 0 ; k < 4 ; k++ )
                        m[i][j][k] = 1;
                }
             }
        }
        for ( int i = 1 ; i <= n ; i++ )
        {
            //scanf ( "%s" , s[i]+1 );
            for ( int j = 1 ; j <= n ; j++ )
            {
                if ( s[i][j] == 'N' )
                    for ( int k = 1 ; k < 2 ; k++ )
                    {
                        for ( int z = 0 ; z < 4 ; z++ ) m[i][j][z] = 2;
                        if ( i-k >= 0 && m[i-k][j][0] != -1 ) 
                            m[i-k][j][0] = 2;
                        if ( m[i][j+k][1] != -1 )
                            m[i][j+k][1] = 2;
                        if ( m[i+k][j][2] != -1 )
                            m[i+k][j][2] = 2;
                        if ( j-k >= 0 && m[i][j-k][3] != -1 )
                            m[i][j-k][3] = 2;
                    }
                if ( s[i][j] == 'S' )
                    for ( int k = 1 ; k < 2 ; k++ )
                    {
                        for ( int z = 0 ; z < 4 ; z++ ) m[i][j][z] = 2;
                        if ( m[i+k][j][0] != -1 )
                            m[i+k][j][0] = 2;
                        if ( j-k >= 0 && m[i][j-k][1] != -1 )
                            m[i][j-k][1] = 2;
                        if ( i-k >= 0 && m[i-k][j][2] != -1 )
                            m[i-k][j][2] = 2;
                        if ( m[i][j+k][3] != -1 )
                            m[i][j+k][3] = 2;
                    }
                if ( s[i][j] == 'W' )
                    for ( int k = 1 ; k < 2 ; k++ )
                    {
                        for ( int z = 0 ; z < 4 ; z++ ) m[i][j][z] = 2;
                        if ( j-k >= 0 && m[i][j-k][0] != -1 )
                            m[i][j-k][0] = 2;
                        if ( i-k >= 0 && m[i-k][j][1] != -1 )
                            m[i-k][j][1] = 2;
                        if ( m[i][j+k][2] != -1 )
                            m[i][j+k][2] = 2;
                        if ( m[i+k][j][3] != -1 )
                            m[i+k][j][3] = 2;
                    }
                if ( s[i][j] == 'E' )
                    for ( int k = 1 ; k < 2 ; k++ )
                    {
                        for ( int z = 0 ; z < 4 ; z++ ) m[i][j][z] = 2;
                        if ( m[i][j+k][0] != -1 )
                            m[i][j+k][0] = 2;
                        if ( m[i+k][j][1] != -1 )
                            m[i+k][j][1] = 2;
                        if ( j-k >= 0 && m[i][j-k][2] != -1 )
                            m[i][j-k][2] = 2;
                        if ( i-k >= 0 && m[i-k][j][3] != -1 )
                            m[i-k][j][3] = 2;
                    }
            }
        }
        /*
        for ( int k = 0 ; k < 4 ; k++ )
        {
            cout << "____________________________________" << endl;
            for ( int i = 0 ; i <= n+1 ; i++ )
            {
                for ( int j = 0 ; j <= n+1 ; j++ )
                    cout << setw(2) << m[i][j][k] << " ";
                cout << endl;
            }
            cout << "____________________________________" << endl;
        }
        */        
        printf ( "Case #%d: %d\n" , c++ , bfs () );
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值