题目链接:POJ-3984
思路:需要保存路径,所以开个结构体数组 BFS
AC代码
#include <iostream>
#include <algorithm>
#include<math.h>
#include<queue>
#include<cstring>
using namespace std;
typedef long long LL;
const int maxn = 10000;
bool inq[8][8];
char maze[8][8];
int X[4] = {1, -1, 0, 0};
int Y[4] = {0, 0, 1, -1};
struct node{
int x, y;
int pre;
int index;
node(){
pre = -1;
}
}way[100];
bool check(node now){
if(now.x < 0 || now.x >= 5 || now.y < 0 || now.y >= 5)
return 0;
if(maze[now.x][now.y] == '1')
return 0;
return 1;
}
node BFS(){
way[0].x = 0;
way[0].y = 0;
queue<node> q;
inq[way[0].x][way[0].y] = 1;
q.push(way[0]);
int count = 1;
while(!q.empty()){
node now = q.front();
q.pop();
if(now.x == 4 && now.y == 4){
return now;
}
node next;
for(int i = 0; i < 4; i++){
next.x = now.x + X[i];
next.y = now.y + Y[i];
if(!inq[next.x][next.y] && check(next)){
inq[next.x][next.y] = 1;
next.pre = now.index;
next.index = count;
way[count] = next;
count ++;
q.push(next);
}
}
}
}
void DFS(int k){
if(k == -1){
return ;
}else{
DFS(way[k].pre);
cout << "(" << way[k].x << ", " << way[k].y << ")" << endl;
}
}
int main(){
memset(inq, 0, sizeof(inq));
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j ++){
cin >> maze[i][j];
}
getchar();
}
for(int i = 0; i < 100; i++){
way[i].index = i;
}
node end;
end = BFS();
int k = end.pre;
DFS(k);
cout << "(" << end.x << ", " << end.y << ")" << endl;
return 0;
}
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int Map[6][6],vis[6][6],pre[110];
//pre[]记录每个状态的前一个状态
struct Cam
{
int x,y;
}List[110];
int Dire[4][2] = {-1,0,1,0,0,-1,0,1}; //上下左右四个方向
int Go(int x,int y) //判断是否可走
{
if(x >= 0 && x < 5 && y >= 0 && y < 5 && Map[x][y] == 0)
return 1;
return 0;
}
void Print(int x) //留下宝藏路线
{
int t;
t = pre[x];
if(t == 0)
{
printf("(0, 0)\n");
printf("(%d, %d)\n",List[x].x,List[x].y);
return ;
}
else//递归输出大法,意思就是说你找到宝藏也是不容易的,进入递归然后一层进(进入上一个位置),在一层一层进,(直到t==0开始输入),(从(0,0)开始返回)再一层一层输出
Print(t);
printf("(%d, %d)\n",List[x].x,List[x].y);
}
void BFS()
{
memset(vis,0,sizeof(vis));
int Head = 0,Tail = 1;
List[0].x = 0;
List[0].y = 0;
pre[0] = -1;//这个pre设置的非常巧妙,直接解决了如何准确找上一步的操作(在下佩服,希望大家下去好好理解下怎么实现,为什么需要这个pre,很重要,是这个题的难点)
while(Head < Tail)
{
int x = List[Head].x;//更新目前的位置
int y = List[Head].y;
if(x == 4 && y == 4)
{
Print(Head);//我找到了海贼王留下的宝藏
return ;
}
for(int i = 0; i < 4; ++i)
{
int xx = x + Dire[i][0];//遍历4个位置
int yy = y + Dire[i][1];
if( !vis[xx][yy] && Go(xx,yy) )//能走并且没有走过
{
vis[xx][yy] = 1;//标记
List[Tail].x = xx;//把这个点给标记下存下来,为了输出路径
List[Tail].y = yy;
pre[Tail] = Head;//标记前一个位置,就是你现在位置是Tail,上一个位置是Head,与你标记的路径是匹配输出的
Tail++;为了更新pre
}
}
Head++;
}
return ;
}
int main()
{
for(int i = 0; i < 5; ++i)
for(int j = 0; j < 5; ++j)
scanf("%d",&Map[i][j]);//建造迷宫
BFS();//开始搜索宝藏哈哈哈
return 0;
}
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int map[7][7];
int vis[7][7];
int to[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
struct none{
int x;
int y;
int pre;
}List[100];
int go(int x,int y){
if(x>=0&&y>=0&&x<5&&y<5&&map[x][y]==0)
return 1;
return 0;
}
int couts(int i){
if(List[i].pre!=-1)
{
couts(List[i].pre);
cout<<"("<<List[i].x<<", "<<List[i].y<<")"<<endl;
}
}
void bfs(){
int rear=1,front=0;
List[0].x=0;
List[0].y=0;
List[0].pre=-1;
vis[0][0]=1;
while(front<rear)
{
for(int i=0;i<4;i++)
{
int xx=List[front].x+to[i][0];
int yy=List[front].y+to[i][1];
if(vis[xx][yy]==0&&go(xx,yy)!=0)
{
vis[xx][yy]=1;
List[rear].x=xx;
List[rear].y=yy;
List[rear].pre=front;
rear++;
}
if(xx==4&&yy==4)
{
couts(front);
}
}
front++;
}
}
int main (){
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
cin>>map[i][j];
memset(vis,0,sizeof(vis));
cout<<"(0, 0)"<<endl;
bfs();
cout<<"(4, 4)"<<endl;
return 0;
}