日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

HDU 1728 逃离迷宫 BFS题

發(fā)布時(shí)間:2023/10/11 95 老码农
生活随笔 收集整理的這篇文章主要介紹了 HDU 1728 逃离迷宫 BFS题 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目描述:輸入一個(gè)m*n的地圖,地圖上有兩種點(diǎn),一種是 . 表示這個(gè)點(diǎn)是空地,是可以走的,另一種是 * ,表示是墻,是不能走的,然后輸入一個(gè)起點(diǎn)和一個(gè)終點(diǎn),另外有一個(gè)k輸入,現(xiàn)在要你確定能否在轉(zhuǎn)k次彎之前從起點(diǎn)到達(dá)終點(diǎn)。

解題報(bào)告:首先說(shuō)下這題坑的地方,就是輸入起點(diǎn)和終點(diǎn)的坐標(biāo)的時(shí)候,不是按照x1,y1,x2,y2輸入的,而是按照y1,x1,y2,x2的順序輸入的。這題搞了很久 ,就是一開(kāi)始沒(méi)有想到怎么解決得到最小轉(zhuǎn)彎次數(shù)的方法,一開(kāi)始試過(guò)重復(fù)訪問(wèn)點(diǎn),但是這樣超內(nèi)存了,然后如果不重復(fù)訪問(wèn)的話又會(huì)得不到轉(zhuǎn)彎次數(shù)最小的點(diǎn),就是說(shuō)假如一個(gè)點(diǎn)從一條路線上被更新過(guò)的話,下一次從另一條路線上就不能再一次更新了,即使如果按照第二次走的路線轉(zhuǎn)彎的次數(shù)會(huì)更少的 話。看了別人解題報(bào)告才想到,可以這樣來(lái)解決就是當(dāng)走到一個(gè)點(diǎn)時(shí),如果可以沿著這條線直走的話,就一直走下去,除非到了邊界,或者碰到墻,同時(shí)是否將這點(diǎn)放入隊(duì)列的話也要做出相應(yīng)的 改變,因?yàn)樽叩臅r(shí)候只要不是墻都能走,但是 不能把所有的點(diǎn)都放進(jìn)隊(duì)列,所以我們可以將從沒(méi)有走過(guò)并且是可以走的點(diǎn)放進(jìn)隊(duì)列,而把已經(jīng)走過(guò)的點(diǎn)不放進(jìn)隊(duì)列,這樣就可以解決超內(nèi)存的問(wèn)題了,另外,走完當(dāng)前這個(gè)點(diǎn)之后,不要忘了把這個(gè)點(diǎn)標(biāo)記為已經(jīng)走過(guò)。并且每次走之前判斷是否已經(jīng)到達(dá)了終點(diǎn)、邊界,墻。一開(kāi)始用自己寫(xiě)的隊(duì)列發(fā)現(xiàn)代碼更長(zhǎng),時(shí)間也更長(zhǎng),后來(lái)改用deque雙端隊(duì)列來(lái)寫(xiě),首先代碼只寫(xiě)了5分鐘,而且沒(méi)有調(diào)試一次就AC了,并且時(shí)間更短,內(nèi)存更小,代碼也更短。這里把我手動(dòng)寫(xiě)的隊(duì)列的和用deque的代碼都附上。

手寫(xiě)隊(duì)列代碼:

 #include<cstdio>
#include<cstring>
#include<time.h>
const int MAX = +;
int T,m,n,k,x1,y1,x2,y2;
int xx[] = {-,,,}; //定義移動(dòng)方向
int yy[] = {,,,-};
int map[MAX][MAX];
typedef struct node {
int x,y,dire,time; //dire用來(lái)保存當(dāng)前的方向,time表示走到當(dāng)前步為止,轉(zhuǎn)彎的次數(shù)
node() {
dire = time = ;
}
node *next;
}*LinkList,linklist;
bool bfs() {
LinkList head = NULL,p = NULL,temp;
head = new linklist; //新建隊(duì)列頭結(jié)點(diǎn),頭結(jié)點(diǎn)不放元素
p = new linklist; //便于存取節(jié)點(diǎn)
p->next = NULL;
p->x = x1,p->y =y1; //首先將起點(diǎn)加到隊(duì)尾
head->next = p;
while(head->next!=NULL) {
temp = head->next; //將節(jié)點(diǎn)從隊(duì)首取出
if(temp->x ==x2 && temp->y==y2 && temp->time-<k)
return true; //判斷是否已經(jīng)到達(dá)終點(diǎn)
for(int i = ;i<;++i) { //從當(dāng)前的位置向周圍四個(gè)方向走
int xxx = temp->x + xx[i];
int yyy = temp->y + yy[i];
if(xxx<||xxx>m||yyy<||yyy>n)
continue;
while(map[xxx][yyy]==||map[xxx][yyy]==) { //這一步很重要,如果當(dāng)前走的方向是直的,且可走,則一直走到底,
//但只有從沒(méi)有走過(guò)的點(diǎn)才加入到隊(duì)列中
if(xxx<||xxx>m||yyy<||yyy>n)
break;
if(xxx ==x2 && yyy==y2 && temp->time-<k)
return true; LinkList q = new linklist;
q->next = NULL;
q->x = xxx;
q->y = yyy;
q->dire = i+;
q->time = temp->time;
if(temp->dire != q->dire)
q->time++;
if(!map[xxx][yyy]) { //從沒(méi)走過(guò)的點(diǎn)才加入到隊(duì)列中
q->next = p->next;
p->next = q;
p = p->next;
}
else delete q; //否則刪除新建的這個(gè)點(diǎn)
map[xxx][yyy] = ; //走過(guò)之后標(biāo)記為已走過(guò),這一順序,這句不能放前面
yyy+=yy[i];
xxx+=xx[i];
}
}
head->next = temp->next;
delete temp;
}
return false;
} int main() {
char d;
scanf("%d",&T);
while(T--) {
scanf("%d%d",&m,&n);
memset(map,,sizeof(map));
for(int i = ;i<=m;++i) {
getchar();
for(int j = ;j<=n;++j) {
scanf("%c",&d);
if(d == '*')
map[i][j] = ;
}
}
scanf("%d%d%d%d%d",&k,&y1,&x1,&y2,&x2);
printf(bfs()? "yes\n":"no\n");
}
return ;
}

deque代碼:

 #include<cstdio>
#include<deque>
#include<iostream>
#include<cstring>
using namespace std;
const int MAX = +;
int k,x1,y1,x2,y2,m,n;
int xx[] = {-,,,};
int yy[] = {,,,-};
class node {
public:
int map[MAX][MAX];
bool bfs();
private:
struct Linklist {
int x,y,dire,times;
Linklist() {
dire = times = ;
}
};
};
bool node::bfs() {
deque<Linklist> head;
Linklist p;
p.x = x1,p.y = y1;
head.push_back(p);
deque<Linklist>::iterator iter;
while(head.size()!=) {
iter = head.begin();
for(int i = ;i<;++i) {
int xxx = iter->x + xx[i];
int yyy = iter->y + yy[i];
if(xxx<||xxx>m||yyy<||yyy>n)
continue;
while(map[xxx][yyy]!=) {
if(xxx == x2 && yyy ==y2 && iter->times-<k)
return true;
Linklist q;
q.x = xxx,q.y = yyy;
q.dire = i+;
q.times = iter->times;
if(q.dire != iter->dire)
q.times++;
if(map[xxx][yyy]==)
head.push_back(q);
map[xxx][yyy] = ;
xxx += xx[i];
yyy += yy[i];
if(xxx<||xxx>m||yyy<||yyy>n)
break;
}
}
head.pop_front();
}
return false;
}
int main() {
int T;
char c;
node temp;
scanf("%d",&T);
while(T--) {
scanf("%d%d",&m,&n);
memset(temp.map,,sizeof(temp.map));
for(int i = ;i<=m;++i) {
getchar();
for(int j = ;j<=n;++j) {
scanf("%c",&c);
if(c == '*')
temp.map[i][j] = ;
}
}
scanf("%d%d%d%d%d",&k,&y1,&x1,&y2,&x2);
printf(temp.bfs()? "yes\n":"no\n");
}
return ;
}

總結(jié)

以上是生活随笔為你收集整理的HDU 1728 逃离迷宫 BFS题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。