HDU 1429 胜利大逃亡(续) / SDUT 2193 救基友记3 简单的BFS

题目链接:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2193

题意:给定一个用二维数组表示的地图,地图上标出了起点,终点,带有编号的门和钥匙。问是否能在规定时间内走到终点,若能最少用时为多少。

显然是简单的BFS,重点在于怎么对地图进行标记。在知道后台数据很小的情况下,无耻的用了链表,不晓得还有什么其他高效的方法。


感觉自己最近愈发浮躁啦。。。。


昨晚看了学长的代码,终于顿悟了第三维的作用(话说顿悟的有点晚啊),然后删掉了链表的部分,改成了静态数组,果断从TLE变成了90+ms......


HDU_AC_Code:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cstdlib>

#define LL long long
#define Max(a,b) ((a) > (b) ? (a) : (b))
#define Min(a,b) ((a) < (b) ? (a) : (b))

using namespace std;

struct P
{
    int x,y,key,cost;
};

char Map[30][30];

bool mv[30][30][1<<10];

int n,m,T;

int jx[] = { 0,-1, 0, 1};
int jy[] = { 1, 0,-1, 0};

bool Is_Key(P p,char d)
{
    int i , l;
    for(i = 0,l = 1; i < d-'A'; ++i)
    {
        l <<= 1;
    }
    return (p.key&l);
}

void Get_Key(P &p,char d)
{
    int i,l;
    for(i = 0,l = 1; i < d-'a'; ++i)
    {
        l <<= 1;
    }
    if((p.key&l) == 0)
    {
        p.key += l;
    }
}

void bfs(P st)
{
    queue<P> q;

    q.push(st);

    P ft;

    int i;

    mv[st.x][st.y][st.key] = true;

    while(q.empty() == false)
    {
        ft = q.front();
        q.pop();

        if(ft.cost >= T)
        {
            continue;
        }

        if(Map[ft.x][ft.y] == '^')
        {
            cout<<ft.cost<<endl;
            return ;
        }


        for(i = 0; i < 4; ++i)
        {
            st = ft;
            st.cost++;
            st.x += jx[i];
            st.y += jy[i];

            if(1 <= st.x && st.x <= n && 1 <= st.y && st.y <= m && mv[st.x][st.y][st.key] == false && Map[st.x][st.y] != '*')
            {
                if('A' <= Map[st.x][st.y] && Map[st.x][st.y] <= 'Z')
                {
                    if(Is_Key(st,Map[st.x][st.y]))
                    {
                        mv[st.x][st.y][st.key] = true;
                        q.push(st);
                    }

                }
                else if('a' <= Map[st.x][st.y] && Map[st.x][st.y] <= 'z')
                {
                    Get_Key(st,Map[st.x][st.y]);
                    mv[st.x][st.y][st.key] = true;
                    q.push(st);
                }
                else
                {
                    mv[st.x][st.y][st.key] = true;
                    q.push(st);
                }
            }

        }
    }
    cout<<-1<<endl;
    return ;
}

int main()
{
    int i,j;

    P st;

    while(scanf("%d %d %d",&n,&m,&T) != EOF)
    {
        for(i = 1; i <= n; ++i)
        {
            scanf("%s",Map[i]+1);
        }

        for(i = 1; i <= n; ++i)
        {
            for(j = 1; j <= m; ++j)
            {
                if(Map[i][j] == '@')
                {
                    st.x = i;
                    st.y = j;
                    st.cost = 0;
                    st.key = 0;
                }
                memset(mv[i][j],false,sizeof(mv[i][j]));
            }
        }
        bfs(st);
    }

    return 0;
}



SDUT_AC_Code

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cstdlib>

#define LL long long
#define Max(a,b) ((a) > (b) ? (a) : (b))
#define Min(a,b) ((a) < (b) ? (a) : (b))

using namespace std;

struct P
{
    int x,y,key,cost;
};

struct Sta
{
    int key;
    Sta *next;
}*mv[35][35];

Sta *creat()
{
    Sta *p = (Sta *)malloc(sizeof(Sta));
    p->next = NULL;
    return p;
}

int n,m,T;
int INF = 550000;
int Min_Cost;

char Map[35][35];

int jx[] = { 0, 1, 0,-1};
int jy[] = {-1, 0, 1, 0};

void Add_Sta(P p)
{
    Sta *s = creat();
    s->key = p.key;
    s->next = mv[p.x][p.y]->next;
    mv[p.x][p.y]->next = s;
}

bool Is_Key(P p,char d)
{
    int i,l;
    for(i = 0,l = 1;i < d-'A'; ++i)
    {
        l <<= 1;
    }

    return (p.key&l);
}

void Add_Key(P &p,char d)
{
    int i,l;
    for(i = 0,l = 1;i < d-'a'; ++i)
    {
        l <<= 1;
    }

    if((p.key&l) == 0)
    {
        p.key += l;
    }
}

bool Is_Include(P p)
{
    Sta *q = mv[p.x][p.y]->next;

    while(q != NULL)
    {
        if(q->key == p.key)
            return false;
        q = q->next;
    }
    return true;
}

void bfs(P st)
{
    queue<P> q;

    P ft;

    Add_Sta(st);

    q.push(st);

    while(q.empty() == false)
    {
        ft = q.front();
        q.pop();

        if(ft.cost >= T)
        {
            continue;
        }

        if(Map[ft.x][ft.y] == '^')
        {
            Min_Cost = ft.cost;
            return;
        }

        for(int i = 0;i < 4; ++i)
        {
            st = ft;
            st.x += jx[i];
            st.y += jy[i];
            st.cost++;
            if(1 <= st.x && st.x <= n && 1 <= st.y && st.y <= m && Map[st.x][st.y] != '*' && Is_Include(st))
            {
                if('A' <= Map[st.x][st.y] && Map[st.x][st.y] <= 'Z')
                {
                    if(Is_Key(st,Map[st.x][st.y]))
                    {
                        Add_Sta(st);
                        q.push(st);
                    }
                }
                else if('a' <= Map[st.x][st.y] && Map[st.x][st.y] <= 'z')
                {
                    Add_Key(st,Map[st.x][st.y]);
                    q.push(st);
                    Add_Sta(st);
                }
                else
                {
                    q.push(st);
                    Add_Sta(st);
                }
            }
        }
    }
}

int main()
{

    P st;

    int i,j;

    for(i = 0;i < 30; ++i)
    {
        for(j = 0;j < 30; ++j)
        {
            mv[i][j]= creat();
        }
    }
    while(scanf("%d %d %d",&n,&m,&T) != EOF)
    {
        Min_Cost = INF;

        for(i = 1;i <= n; ++i)
        {
            scanf("%s",Map[i]+1);
        }

        for(i = 1;i <= n; ++i)
        {
            for(j = 1;j <= m; ++j)
            {
                if(Map[i][j] == '@')
                {
                    st.x = i;
                    st.y = j;
                }
                mv[i][j]->next = NULL; 
            }
        }

        st.key = 0;
        st.cost = 0;

        bfs(st);

        if(Min_Cost == INF)
        {
            cout<<-1<<endl;
        }
        else
        {
            cout<<Min_Cost<<endl;
        }
    }
    return 0;
}


你可能感兴趣的:(HDU 1429 胜利大逃亡(续) / SDUT 2193 救基友记3 简单的BFS)