當前位置:首頁 » 操作系統 » c迷宮演算法

c迷宮演算法

發布時間: 2024-01-10 09:05:30

『壹』 迷宮問題,c語言

#include<stdio.h>
int main(void)
{
int maze[100][100];
int MAZE[100][100];
int m,n;
int p,q;

printf("輸入迷宮的行數m,列數n:\n");
scanf("%d%d",&m,&n);
for(p=0;p<=n+1;p++){
maze[0][p]=1;
maze[m+1][p]=1;
}
for(p=1;p<=m;p++){
maze[p][0]=1;
maze[p][n+1]=1;
printf("輸入第%d行迷宮:\n",p);
for(q=1;q<=n;q++){
scanf("%d",&maze[p][q]);
MAZE[p][q]=maze[p][q];

}
}

struct location{
int row;
int col;
}way[100];

int movehoriz[8]={-1,0,1,1,1,0,-1,-1};
int movevert[8]={1,1,1,0,-1,-1,-1,0};

int endrow=m;
int endcol=n;

way[0].row=1;
way[0].col=1;
int start=3;

int i=0;
int k;
int j;
int found=0;

while(!found){
for(k=start;k<start+8;k++){
if((maze[way[i].row+movevert[k%8]][way[i].col+movehoriz[k%8]]==0)&&((i==0)||((way[i].row!=way[i-1].row)||(way[i].col!=way[i-1].col)))){
way[i+1].row=way[i].row+movevert[k%8];
way[i+1].col=way[i].col+movehoriz[k%8];
i++;
start=(k+5)%8;
break;
}
if((way[i].row==endrow)&&(way[i].col==endcol)){
break;
}
if((maze[way[i].row+movevert[k]][way[i].col+movehoriz[k]]==0)&&(way[i].row==way[i-1].row)&&(way[i].col==way[i-1].col)){
way[i].row=0;
way[i].col=0;
maze[way[i].row][way[i].col]=1;
i--;
start=(start+4)%8;
}

}
if(k>=start+8){
break;
}
if((way[i].row==endrow)||(way[i].col==endcol)){
found=1;
break;
}

}

if(found){
for(j=0;j<=i;j++){
printf("maze[%d][%d]\n",way[j].row,way[j].col);
}
}
else{
printf("The maze does not have a path\n");
}

}

QQ:366597114 不一定完全對。也許有小錯誤。有問題可以來問我哈

『貳』 c語言數字迷宮問題怎麼做圖片如下

可以參考八皇後問題用回溯的方式來解決。

這道迷宮題,觀察一下,與某個格子相鄰的格子至多為4個,也就是有4種可能的前進方向,需要窮舉所有可能。在窮舉下一種可能前,需要恢復初始狀態(即回溯)。寫了一個簡單的代碼,還有很多需要優化的地方,但關鍵是能用^_^,你可以調試一下,把實現的思路寫出來,就可以順利完成這道題了。

#include <stdio.h>

#include <string.h>


/***


1、 迷宮大小n*n,擴展為(n+2)*(n+2),外圍一圈的格子作為不可再前進的邊界。

2、 若所有相鄰格子均已訪問,表明此路不通,回溯。

3、 計數器達到總步數,檢查是否位於終點及中間路徑是否合法,通過則顯示。

4、 查找函數Lookup()以遞歸方式反復調用自身,a->b->c->...,以查找某條可能的路徑。

...c,b,a等返回前,均回溯,逐步恢復tag。

離開a時,tag已經恢復到初始狀態,如此就不影響查找其他路徑了。

5、 若迷宮夠大或數據特別,都可能存在不同的路線

6、 先查看main(),了解基本步驟及初始化過程

***/


const int N = 6;


// eg1. N = 6

int row[N] = { 0, 4, 3, 1, 3, 0}; // 4 + 3 + 1 + 3 = 11

int col[N] = { 0, 1, 4, 3, 3, 0};


// eg2. N = 6

//int row[N] = { 0, 3, 4, 4, 2, 0}; // 3 + 4 + 4 + 2 = 13

//int col[N] = { 0, 3, 2, 4, 4, 0};


// eg3. N = 8

//int row[N] = { 0, 3, 1, 4, 3, 3, 1, 0};

//int col[N] = { 0, 1, 1, 5, 3, 1, 4, 0};


// 計數器

// Lookup()用g_counter與COUNTER比較是否走到了規定的步數

int g_counter = 0; // 無論是否成功,每查找一條路徑後自動恢復為0

int COUNTER = 0; // 總步數,等於row(或col)數組各元素之和,在main()中初始化


// Lookup()用tag記錄行走狀況

// 在main()中初始化

// 每查找一條路徑後自動恢復為初始狀態

struct _tag

{

int row[N];

int col[N];

int arr[N][N]; // 走過,按順序標記

} tag;


// 顯示迷宮

// inside為false時,列印擴展的迷宮

// inside為true時,列印未擴展的迷宮

void Display(bool inside)

{

int i, j;


for (i = 0; i < N; i++)

{

if ((i == 0 || i == N-1) && inside)

continue;


for (j = 0; j < N; j++)

{

if ((j == 0 || j == N-1) && inside)

printf("%4s", " ");

else

printf("%4d", tag.arr[i][j]);

}

printf(" ");

}

printf(" ");

}


// 檢查路徑是否符合已給條件

bool Check()

{

bool b = true;

int sum_row, sum_col;


for (int i = 1; i < N-1; i++)

{

sum_row = 0;

sum_col = 0;

for (int j = 1; j < N-1; j++)

{

sum_row += tag.arr[i][j] > 0 ? 1 : 0;

sum_col += tag.arr[j][i] > 0 ? 1 : 0;

}


if (sum_row != row[i] || sum_col != col[i])

{

b = false;

break;

}

}


return b;

}


// 遞歸查找路徑,返回前擦除痕跡,恢復現場

// 當前訪問的格子(i,j),i:行坐標,j:列坐標

void Lookup(int i, int j)

{

g_counter++; // 總步數加1

tag.arr[i][j] = g_counter; // visited

tag.row[i]--; // 行計數減1

tag.col[j]--; // 列計數減1


// 走完了

if (g_counter >= COUNTER)

{

// 位於終點,且路徑合法

if (i == N-2 && j == N-2 && Check())

{

Display(true);

}


// 此格子已判別,恢復現場,以查找其他路徑(此即回溯的思想)

tag.arr[i][j] = 0;

tag.row[i]++;

tag.col[j]++;

g_counter--;


return;

}



// 行方向

if (tag.row[i] > 0)

{

if (!tag.arr[i][j+1])

{

Lookup(i, j+1); // 從當前格子向右走一步

}


if (!tag.arr[i][j-1])

{

Lookup(i, j-1); // 從當前格子向左走一步

}

}


// 列方向

if (tag.col[j] > 0)

{

if (!tag.arr[i+1][j])

{

Lookup(i+1, j); // 從當前格子向下走一步

}


if (!tag.arr[i-1][j])

{

Lookup(i-1, j); // 從當前格子向上走一步

}


}


// 此格子已判別,恢復現場,以查找其他路徑(此即回溯的思想)

tag.arr[i][j] = 0;

tag.row[i]++;

tag.col[j]++;

g_counter--;

}


int main()

{

// 格子初始化為全0

memset(tag.arr, 0, sizeof(tag.arr));


for (int i = 0; i < N; i++)

{

tag.row[i] = row[i];

tag.col[i] = col[i];

COUNTER += row[i];


tag.arr[0][i] = 1;

tag.arr[N-1][i] = 1;

tag.arr[i][0] = 1;

tag.arr[i][N-1] = 1;

}

printf("初始化: ");

Display(false);


printf("合法路徑: ");

Lookup(1, 1); // 從格子(1, 1)出發


//getchar();

return 0;

}

『叄』 用C/C++編寫迷宮,用A*演算法

#include "stdafx.h"
#include <stack>
using namespace std;

//定義常數
const int rows = 8,cols = 8;

//聲明全局變數�
HINSTANCE hInst;
HBITMAP ball;
HDC hdc,mdc,bufdc;
HWND hWnd;
DWORD tPre,tNow;
char *str;//記錄目前搜索狀態的字元串指針
int nowPos,prePos;
bool find;//聲明一個布爾變數,以記錄是否找到迷宮出口
stack<int> path;//建立一個整型堆棧path

int mapIndex[rows*cols] = { 0,2,0,0,0,0,0,0,
0,1,0,1,1,1,1,0,
0,1,0,1,0,1,1,0,
0,1,0,0,0,1,1,0,
0,1,1,1,1,1,1,0,
0,1,0,0,0,0,1,0,
0,0,1,1,1,1,1,0,
0,0,0,0,0,0,3,0 };
int record[rows*cols];

ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void MyPaint(HDC hdc);

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;

MyRegisterClass(hInstance);

if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}

while( msg.message!=WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0,0 ,PM_REMOVE) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
tNow = GetTickCount();
if(tNow-tPre >= 100)
MyPaint(hdc);
}
}

return msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "canvas";
wcex.hIconSm = NULL;

return RegisterClassEx(&wcex);
}

//*****************************************
// 1.迷宮拼接地圖
// 2.設定小球在迷宮入口處
// 3.按照mapIndex設定record數組的初始內容
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HBITMAP bmp;
hInst = hInstance;

hWnd = CreateWindow("canvas", "迷宮" , WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

if (!hWnd)
{
return FALSE;
}

MoveWindow(hWnd,10,10,430,450,true);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

hdc = GetDC(hWnd);
mdc = CreateCompatibleDC(hdc);
bufdc = CreateCompatibleDC(hdc);

bmp = CreateCompatibleBitmap(hdc,cols*50,rows*50);
SelectObject(mdc,bmp);

HBITMAP tile;
int rowNum,colNum;
int i,x,y;
//載入點陣圖
tile = (HBITMAP)LoadImage(NULL,"tile.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);
ball = (HBITMAP)LoadImage(NULL,"ball.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);

for (i=0;i<rows*cols;i++)
{
record[i] = mapIndex[i];

rowNum = i / cols; //求列編號
colNum = i % cols; //求行編號
x = colNum * 50; //求貼圖X坐標
y = rowNum * 50; //求貼圖Y坐標

SelectObject(bufdc,tile);

if(!mapIndex[i]) //如果是0,就貼牆
BitBlt(mdc,x,y,50,50,bufdc,0,0,SRCCOPY);
else //通道
{
if(mapIndex[i] == 2) //找到迷宮出口
{
nowPos = i;
path.push(i);
record[i] = 0;
}
BitBlt(mdc,x,y,50,50,bufdc,0,0,WHITENESS);//WHITENESS 白色50*50的方塊
}
}
prePos = cols * rows + 1;

MyPaint(hdc);

return TRUE;
}

//*************************************
// 搜尋可行走路徑及小球移動貼圖
void MyPaint(HDC hdc)
{
int rowNum,colNum;
int x,y;
int up,down,left,right;

//清除上次貼圖
rowNum = prePos / cols;
colNum = prePos % cols;
x = colNum * 50;
y = rowNum * 50;

SelectObject(bufdc,ball);
BitBlt(mdc,x,y,50,50,bufdc,0,0, WHITENESS);

//貼小球
rowNum = nowPos / cols;
colNum = nowPos % cols;
x = colNum * 50;
y = rowNum * 50;

SelectObject(bufdc,ball);
BitBlt(mdc,x,y,50,50,bufdc,0,0, SRCCOPY);

if(!find)
{
str = "搜尋出口中...";

up = nowPos - cols;
down = nowPos + cols;
left = nowPos - 1;
right = nowPos + 1;

if(up>=0 && record[up]) //往上走�
{
path.push(up);
record[up] = 0;
prePos = nowPos;
nowPos = up;

if(mapIndex[nowPos] == 3) //找到出口
find = true;
}
else if(down<=cols*rows-1 && record[down]) //下
{
path.push(down);
record[down] = 0;
prePos = nowPos;
nowPos = down;

if(mapIndex[nowPos] == 3)
find = true;
}
else if(left>=rowNum*cols && record[left]) //左
{
path.push(left);
record[left] = 0;
prePos = nowPos;
nowPos = left;

if(mapIndex[nowPos] == 3)
find = true;
}
else if(right<=(rowNum+1)*cols-1 && record[right]) //右
{
path.push(right);
record[right] = 0;
prePos = nowPos;
nowPos = right;

if(mapIndex[nowPos] == 3)
find = true;
}
else //無�
{
if(path.size() <= 1) //回到入口����
str = "迷宮沒有出口...";
else
{
path.pop();
prePos = nowPos;
nowPos = path.top();
}
}
}
else
{
str = "找到出口了!";
}

TextOut(mdc,0,0,str,strlen(str));
BitBlt(hdc,10,10,cols*50,rows*50,mdc,0,0,SRCCOPY);

tPre = GetTickCount();
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_KEYDOWN:
if(wParam==VK_ESCAPE)
PostQuitMessage(0);
break;
case WM_DESTROY:
DeleteDC(mdc);
DeleteDC(bufdc);
DeleteObject(ball);

ReleaseDC(hWnd,hdc);

PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

『肆』 C語言迷宮問題,求該演算法的時間和空間的復雜度。迷宮的路徑已經定義好,求出路的演算法。

該演算法是不穩定的,其時空復雜度不僅和m,n有關,還和mg[][]的具體數值有關。
最壞情況下:每個點都試探過才走到終點。此時時間復雜度為:(m*n-1)*4,(其中4為4個方向),空間復雜度m*n*2,(其中m*n為存儲迷宮圖空間,m*n為棧空間);
再好情況下:一次試探過就走到終點。此時時間復雜度為:(min(m,n)-1),空間復雜度m*n;

所以:
該演算法時間復雜度為:[(m*n-1)*4+(min(m,n)-1)]/2,約為2×m×n
空間復雜度為3*m*n/2

『伍』 求解c語言一遞歸迷宮問題

給你給偽演算法:(設坐標為x,y,坐標向右和下延生。)
函數:

判斷當前是不是(7,7),如果是,表示走出迷宮。列印軌跡
1 嘗試往左先走一步(x-1,如果x小於0,或者對應位置標識為阻塞)
2 1如果成功,用本函數遞歸調用左走一步的坐標,並記下當前位置到軌跡列表。
3 嘗試往前先走一步(y+1,如果y小於0,或者對應位置標識為阻塞)
4 3如果成功,用本函數遞歸調用前走一步的坐標,並記下當前位置到軌跡列表。
5 嘗試往右先走一步(x+1,如果x小於0,或者對應位置標識為阻塞)
6 5如果成功,用本函數遞歸調用前走一步的坐標,並記下當前位置到軌跡列表。
如果是(0,0),表示沒有合適的路徑可走出迷宮。
如果不是(0,0),將軌跡列表最後一位彈出。

『陸』 c語言,用二維數組解決迷宮問題。來段完整的代碼吧。

好的,以下是使用二維數組解決迷宮問題的C語言代碼示例:

Copy code
#include <stdio.h>

#define ROW 6 // 迷宮行數
#define COL 6 // 迷宮列數

int maze[ROW][COL] = { // 迷宮地圖 1表兄銀碰示障礙,0表示通路
{1, 1, 1, 1, 1, 1},
{1, 0, 0, 1, 0, 1},
{1, 0, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 0, 1},
{1, 1, 1, 1, 1, 1},
};

int result[ROW][COL]; // 存放走迷宮的結果

int dfs(int row, int col) {
if (row == ROW - 1 && col == COL - 1) { // 到達終點
result[row][col] = 1;
return 1;
}
if (maze[row][col] == 0) { // 當前位置是通路
result[row][col] = 1;
if (row < ROW - 1 && dfs(row + 1, col)) { // 向下走有解
return 1;
}
if (col < COL - 1 && dfs(row, col + 1)) { // 向右走有解
return 1;
}
result[row][col] = 0; // 標記走過的路
}
return 0; // 返回無解羨談
}

void print_result() {
printf("走迷宮的結果:\n");
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
printf("%d ", result[i][j]);
}
printf("\n");
}
}

int main() {
if (dfs(0, 0)) { // 從起點開始走迷宮
print_result();
} else {
printf("無法走出迷宮!\n");
}
return 0;
}
上述搏碰代碼中,我們使用了一個二維數組 maze 來表示迷宮地圖,其中 1 表示障礙,0 表示通路;另一個二維數組 result 用來存儲走迷宮的結果,其中 1 表示該位置走通了, 0 表示該位置沒有走通。

我們使用 dfs 函數來進行深度優先搜索,從起點 (0, 0) 開始往下、往右走,直到走到終點 (ROW-1, COL-1),如果存在通路,則將路徑標記在 result 數組中,並返回 1,否則返回 0 表示無解。

最後,我們在 main 函數中調用 dfs 函數,判斷是否能從起點走出迷宮,如果有解,則輸出走迷宮的結果;否則,輸出 "無法走出迷宮" 的提示。

熱點內容
怎麼用安卓手機查蘋果的序列號 發布:2024-11-29 06:21:08 瀏覽:507
r11s原始密碼是多少 發布:2024-11-29 05:52:20 瀏覽:79
c語言枚舉法 發布:2024-11-29 05:50:58 瀏覽:125
大數據系統如何配置 發布:2024-11-29 05:48:44 瀏覽:89
連戰訪問西安小學 發布:2024-11-29 05:45:03 瀏覽:316
怎麼編譯原生安卓手機 發布:2024-11-29 05:44:28 瀏覽:193
java代碼編譯java文件 發布:2024-11-29 05:44:27 瀏覽:208
如何部署遠程伺服器 發布:2024-11-29 05:34:37 瀏覽:523
紅米系統存儲與手機存儲 發布:2024-11-29 05:33:55 瀏覽:198
qt反編譯工具 發布:2024-11-29 05:29:31 瀏覽:480