数据结构作业 迷宫问题 模拟 之基础的BFS DFS

题目要求老鼠Pzjay从(1,1)出发,到达右下角(或指定位置)是否有路径(DFS),并求最短路径(BFS),DFS是顺序输出路径的,而BFS是逆序输出的(改成顺序输出EASY,就不改了)。貌似DFS也能求最佳路径,但代码量比较可观,BFS!

求最短路径dfs也可以,不过ms麻烦哩狠狠,故而bfs代替之。为何bfs找到的就是最佳路径呢,据leefour讲:因为

每次入列的均是上个走过的坐标的最近点,并且宽搜是遍历完当前所有入列的点(即八个方向的坐标)后才探寻下一步

,不同于dfs的一条道走到死才回头,所以dfs找到的路径是随机的,而bfs则是最短路径,Orz。
放码子:

//dfs版: #include<iostream> #include<deque> #define nax 100 using namespace std; typedef struct mi { int x; int y; }pzjj; int line,col,num=0; int maze[nax][nax]; int dir[8][2] ={-1,0,-1,1,0,1,1,1,1,0,1,-1,0,-1,-1,-1}; pzjj mouse[nax]; bool dfs(int a,int b)//dfs最好返回bool值,容易处理 { mouse[num].x=a; mouse[num].y=b;//将当前坐标记录 num++; if(a==line && b==col) return true; int i; int lx,ly; for(i=0;i<8;i++) { lx=a+dir[i][0]; ly=b+dir[i][1]; if((lx<=line && ly<=col && lx>0 && ly>0) && maze[lx][ly]==1) { maze[lx][ly]=0;//标记走过 int _t = num;//记录下当前num值 bool t = dfs(lx,ly); if(t)//如果走得通或到达终点 return true; num = _t;//否则num回到dfs之前的值 maze[lx][ly]=1;//撤销标记 } } return false;//走到此说明此路不通 } int main() { int i,j; scanf("%d%d",&line,&col); memset(maze,0,sizeof(maze)); for(i=1;i<=line;i++) for(j=1;j<=col;j++) scanf("%d",&maze[i][j]);//1表示通过,0表示障碍 if(!dfs(1,1)) { printf("死路/n"); return false; } for(i=0;i<num;i++) printf("%d %d/n",mouse[i].x,mouse[i].y); return false; } //bfs版:其输出的路径是倒叙的 #include<iostream> using namespace std; int dir[8][2] ={-1,0,-1,1,0,1,1,1,1,0,1,-1,0,-1,-1,-1}; int maze[100][100]; typedef struct pp { int x,y,pre; }pzjj; pzjj mouse[100]; void display(int tail) { int i=tail; do { printf("%d %d/n",mouse[i].x,mouse[i].y); i=mouse[i].pre; }while(i!=0); } void bfs(int line,int col) { int i,lx,ly; bool find=false; int front=1,rear=1; mouse[1].x=1,mouse[1].y=1,mouse[1].pre=0;//初始化,从1,1开走 while(front<=rear && !find) { for(i=0;i<8;i++)//开始搜 { lx=mouse[front].x+dir[i][0]; ly=mouse[front].y+dir[i][1]; if(maze[lx][ly]==1) { rear++; mouse[rear].x=lx; mouse[rear].y=ly; mouse[rear].pre=front; maze[lx][ly]=0;//标记走过 } if(lx==line && ly==col) { display(rear); find=true; } } front++; } if(!find) printf("死路/n"); } int main() { int i,j; int col,line; scanf("%d%d",&line,&col); memset(maze,0,sizeof(maze)); for(i=1;i<=line;i++) for(j=1;j<=col;j++) scanf("%d",&maze[i][j]);//1表示通过,0表示障碍 bfs(line,col); return false; } 后来小慧姐让灰得让用栈写这个迷宫求解,补一个栈模拟递归的: #include<iostream> #include<stack> using namespace std; const int sup=200; const int dir[4][2]={0,1,1,0,-1,0,0,-1}; struct Pzjay// { int x; int y; void operator=(const Pzjay &tmp) { this->x=tmp.x; this->y=tmp.y; }; bool operator==(const Pzjay &b) { return (this->x==b.x && this->y==b.y); }; }path[sup][sup];//path[i][j]记录一条路径上(i,j)位置的前一个位置 bool used[sup][sup]; int matr[sup][sup]; Pzjay beg,end; stack <Pzjay> st; bool dfs(int row,int column,int &sum) { int i,j; st.push(beg); Pzjay top,temp; while(!st.empty())//栈不空继续探索 { top=st.top(); st.pop(); used[top.x][top.y]=true; if(top==end) return true; for(i=0;i<4;++i)//探索四个方向是否可以通行 { temp.x=top.x+dir[i][0]; temp.y=top.y+dir[i][1]; if(!used[temp.x][temp.y] && matr[temp.x][temp.y])//没访问过并且是通路 { st.push(temp); path[temp.x][temp.y]=top; } } } return false; } int main() { int R; int C; int sum=0;//记录路径步数 memset(matr,0,sizeof(matr)); memset(used,false,sizeof(used)); scanf("%d%d",&R,&C);//输入迷宫行数列数 int i,j; for(i=1;i<=R;++i) for(j=1;j<=C;++j) scanf("%d",&matr[i][j]);//matr[i][j]=1表示此处可以通行,matr[i][j]=0表示此处不通 beg.x=beg.y=1; end.x=R; end.y=C; if(dfs(R,C,sum)) { printf("Bingo/n"); do { printf("%d %d/n",end.x,end.y); end=path[end.x][end.y];//从终点倒溯回去 }while(end.x!=beg.x || end.y!=beg.y); cout<<end.x<<" "<<end.y<<endl; } else printf("No way!/n"); return 'Pz'; } 双广版: #include<iostream> using namespace std; const int sup=505; const int dir[4][2]={0,1,1,0,-1,0,0,-1}; struct maze { int x; int y; void operator=(const maze &tmp) { this->x=tmp.x; this->y=tmp.y; }; bool operator==(const maze &b) { return (this->x==b.x && this->y==b.y); }; }stack[sup*sup];//path[sup][sup];//path[i][j]??????????????(i,j)???????????????? int used[sup][sup]; int matr[sup][sup]; maze beg,end; bool Hot_Girl(int row,int column) { int i,j,head(0),tail(0); stack[tail++]=beg; stack[tail++]=end; used[beg.x][beg.y]='P'; used[end.x][end.y]='z'; maze top,temp; while(head<tail)//?????????????? { top=stack[head++]; head%=(row*column); tail%=(row*column); /*if(used[top.x][top.y]==122) cout<<"top "<<num<<" "<<top.x<<" "<<top.y<<endl;*/ for(i=0;i<4;++i)//???????????????????????? { temp.x=top.x+dir[i][0]; temp.y=top.y+dir[i][1]; if(matr[temp.x][temp.y])//?????????????????? { if(0==used[temp.x][temp.y]) { used[temp.x][temp.y]=used[top.x][top.y]; stack[tail++]=temp; } else if(used[temp.x][temp.y]!=used[top.x][top.y]) return true; } } } return false; } int main() { int R; int C; for(int i=0;i<sup;++i) fill(used[i],used[i]+sup,0); //freopen("1.txt","r",stdin); memset(matr,0,sizeof(matr)); scanf("%d%d",&R,&C);//???????????????? int i,j; for(i=1;i<=R;++i) for(j=1;j<=C;++j) scanf("%d",&matr[i][j]);//matr[i][j]=1??????????????????matr[i][j]=0???????????? beg.x=beg.y=1; end.x=R; end.y=C; if(Hot_Girl(R,C)) { printf("Bingo/n"); //do //{ // pzj[end.x][end.y]='@'; // //printf("%d %d/n",end.x,end.y); // end=path[end.x][end.y];//?????????????? //}while(end.x!=beg.x || end.y!=beg.y); //pzj[end.x][end.y]='@'; //freopen("out.txt","w",stdout); //for(i=1;i<=R;++i) //{ // for(j=1;j<=C;++j) // printf("%c ",pzj[i][j]); // printf("/n"); //} ////cout<<end.x<<" "<<end.y<<endl; } else printf("No way/n"); return 0; }

 

不系本人自恋,实在是有些无耻的站点不啃声就把码字拿走了,然后装的极其若无其事

 

附测试数据:

7 8
1 0 0 0 0 0 1 0
1 0 0 0 0 1 0 1
1 0 0 0 1 0 0 1
1 0 0 0 0 1 0 1
1 0 1 0 1 0 0 1
0 1 0 1 0 0 1 0
0 0 0 0 0 0 0 1


answer:
1 1
2 1
3 1
4 1
5 1
6 2
5 3
6 4
5 5
4 6
3 5
2 6
1 7
2 8
3 8
4 8
5 8
6 7
7 8

这个目测就知道是否正确,不给答案了!

4 4
1 0 0 1
0 1 0 1
1 0 1 1
0 1 1 1

 

你可能感兴趣的:(数据结构,c,struct,测试,Path,作业)