當前位置:首頁 » 編程語言 » 數字迷宮c語言

數字迷宮c語言

發布時間: 2023-09-04 12:43:34

『壹』 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;

}

熱點內容
滑板鞋腳本視頻 發布:2025-02-02 09:48:54 瀏覽:433
群暉怎麼玩安卓模擬器 發布:2025-02-02 09:45:23 瀏覽:557
三星安卓12彩蛋怎麼玩 發布:2025-02-02 09:44:39 瀏覽:744
電腦顯示連接伺服器錯誤 發布:2025-02-02 09:24:10 瀏覽:537
瑞芯微開發板編譯 發布:2025-02-02 09:22:54 瀏覽:147
linux虛擬機用gcc編譯時顯示錯誤 發布:2025-02-02 09:14:01 瀏覽:240
java駝峰 發布:2025-02-02 09:13:26 瀏覽:652
魔獸腳本怎麼用 發布:2025-02-02 09:10:28 瀏覽:538
linuxadobe 發布:2025-02-02 09:09:43 瀏覽:212
sql2000資料庫連接 發布:2025-02-02 09:09:43 瀏覽:726