您的位置:首页 > 其它

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

2013-11-08 19:06 429 查看
题目链接: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: