?? algo3-5.cpp
字號:
// algo3-5.cpp 利用棧求解迷宮問題(只輸出一個解,算法3.3)
#include<string.h>
#include<ctype.h>
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()
#include<io.h> // eof()
#include<math.h> // floor(),ceil(),abs()
#include<process.h> // exit()
#include<iostream.h> // cout,cin
// 函數結果狀態代碼
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
// #define OVERFLOW -2 因為在math.h中已定義OVERFLOW的值為3,故去掉此行
typedef int Status; // Status是函數的類型,其值是函數結果狀態代碼,如OK等
typedef int Boolean; // Boolean是布爾類型,其值是TRUE或FALSE
struct PosType // 迷宮坐標位置類型
{
int x; // 行值
int y; // 列值
};
#define MAXLENGTH 25 // 設迷宮的最大行列為25
typedef int MazeType[MAXLENGTH][MAXLENGTH]; // 迷宮數組類型[行][列]
// 全局變量
MazeType m; // 迷宮數組
int x,y; // 迷宮的行數,列數
PosType begin,end; // 迷宮的入口坐標,出口坐標
void Print()
{ // 輸出迷宮的解(m數組)
int i,j;
for(i=0;i<x;i++)
{
for(j=0;j<y;j++)
printf("%3d",m[i][j]);
printf("\n");
}
}
void Init(int k)
{ // 設定迷宮布局(墻為值0,通道值為k)
int i,j,x1,y1;
printf("請輸入迷宮的行數,列數(包括外墻):");
scanf("%d,%d",&x,&y);
for(i=0;i<x;i++) // 定義周邊值為0(外墻)
{
m[0][i]=0; // 行周邊
m[x-1][i]=0;
}
for(i=0;i<y-1;i++)
{
m[i][0]=0; // 列周邊
m[i][y-1]=0;
}
for(i=1;i<x-1;i++)
for(j=1;j<y-1;j++)
m[i][j]=k; // 定義除外墻,其余都是通道,初值為k
printf("請輸入迷宮內墻單元數:");
scanf("%d",&j);
printf("請依次輸入迷宮內墻每個單元的行數,列數:\n");
for(i=1;i<=j;i++)
{
scanf("%d,%d",&x1,&y1);
m[x1][y1]=0; // 修改墻的值為0
}
printf("迷宮結構如下:\n");
Print();
printf("請輸入入口的行數,列數:");
scanf("%d,%d",&begin.x,&begin.y);
printf("請輸入出口的行數,列數:");
scanf("%d,%d",&end.x,&end.y);
}
int curstep=1; // 當前足跡,初值(在入口處)為1
struct SElemType // 棧的元素類型
{
int ord; // 通道塊在路徑上的"序號"
PosType seat; // 通道塊在迷宮中的"坐標位置"
int di; // 從此通道塊走向下一通道塊的"方向"(0~3表示東~北)
};
#include"c3-1.h" // 采用順序棧存儲結構
#include"bo3-1.cpp" // 采用順序棧的基本操作函數
// 定義墻元素值為0,可通過路徑為1,不能通過路徑為-1,通過路徑為足跡
Status Pass(PosType b)
{ // 當迷宮m的b點的序號為1(可通過路徑),返回OK;否則,返回ERROR
if(m[b.x][b.y]==1)
return OK;
else
return ERROR;
}
void FootPrint(PosType a)
{ // 使迷宮m的a點的值變為足跡(curstep)
m[a.x][a.y]=curstep;
}
void NextPos(PosType &c,int di)
{ // 根據當前位置及移動方向,求得下一位置
PosType direc[4]={{0,1},{1,0},{0,-1},{-1,0}}; // {行增量,列增量},移動方向,依次為東南西北
c.x+=direc[di].x;
c.y+=direc[di].y;
}
void MarkPrint(PosType b)
{ // 使迷宮m的b點的序號變為-1(不能通過的路徑)
m[b.x][b.y]=-1;
}
Status MazePath(PosType start,PosType end) // 算法3.3
{ // 若迷宮m中存在從入口start到出口end的通道,則求得一條
// 存放在棧中(從棧底到棧頂),并返回TRUE;否則返回FALSE
SqStack S; // 順序棧
PosType curpos; // 當前位置
SElemType e; // 棧元素
InitStack(S); // 初始化棧
curpos=start; // 當前位置在入口
do
{
if(Pass(curpos))
{ // 當前位置可以通過,即是未曾走到過的通道塊
FootPrint(curpos); // 留下足跡
e.ord=curstep;
e.seat=curpos;
e.di=0;
Push(S,e); // 入棧當前位置及狀態
curstep++; // 足跡加1
if(curpos.x==end.x&&curpos.y==end.y) // 到達終點(出口)
return TRUE;
NextPos(curpos,e.di); // 由當前位置及移動方向,確定下一個當前位置
}
else
{ // 當前位置不能通過
if(!StackEmpty(S)) // 棧不空
{
Pop(S,e); // 退棧到前一位置
curstep--; // 足跡減1
while(e.di==3&&!StackEmpty(S)) // 前一位置處于最后一個方向(北)
{
MarkPrint(e.seat); // 在前一位置留下不能通過的標記(-1)
Pop(S,e); // 再退回一步
curstep--; // 足跡再減1
}
if(e.di<3) // 沒到最后一個方向(北)
{
e.di++; // 換下一個方向探索
Push(S,e); // 入棧該位置的下一個方向
curstep++; // 足跡加1
curpos=e.seat; // 確定當前位置
NextPos(curpos,e.di); // 確定下一個當前位置是該新方向上的相鄰塊
}
}
}
}while(!StackEmpty(S));
return FALSE;
}
void main()
{
Init(1); // 初始化迷宮,通道值為1
if(MazePath(begin,end)) // 有通路
{
printf("此迷宮從入口到出口的一條路徑如下:\n");
Print(); // 輸出此通路
}
else
printf("此迷宮沒有從入口到出口的路徑\n");
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -