迷宮問題
問題描述:給定乙個m×n的迷宮圖,求所有從指定入口 到出口的路徑。假設迷宮圖如下圖所示(其中m=6,n=6,含 外圍加上一圈不可走的方塊,這樣做的目的是避免在查詢時 出界),迷宮由方塊構成,空白方塊表示可以走的通道,帶 陰影方塊表示不可走的障礙物。 要求所求路徑必須是簡單路徑,即在求得的路徑上不能 重複出現同一空白方塊,而且從每個方塊出發只能走向上下 左右四個相鄰的空白方塊。
用回溯法解決迷宮問題
回溯法=dfs+剪枝函式
回溯法實際上乙個類似窮舉的搜尋嘗試過程,主要是 在搜尋嘗試過程中按照深度優先的方法尋找問題的解,當 發現已不滿足求解條件時,就「回溯(backtracking)」 (即回退,走不通就掉頭),嘗試別的路徑。
回溯法在用來求問題的所有解(或最優解)時,要回 溯到根,且根結點的所有子樹都已被搜尋遍才結束。 • 而在求任一解(存在性問題)時,只要搜尋到乙個解 就結束。 • 這種以深度優先(dfs)的方式系統地搜尋問題的解的 演算法稱為回溯法,它適合於解一些組合數較大的問題。
在解決迷宮問題時,需要注意:1.結束 當起止點座標等於終點 2.走過的點一定要標記,否則會再回溯過去 3.設定乙個函式能控制點上下左右四個方向 4.採用回溯時一定要清理資料。恢復路徑(把走過的點恢復為0等)。
**//迷宮問題
#include
#include
#define row 10
#define col 10
int pathlen=0;
int path[row*col];
int maze[row][col] = ,
, //1
,, //3
,, //5
,, //7
,// 0 3 5 7 9
};void print_maze();
void print_path(int,int);
int make_new_place(int,int,int);
bool dfs(int,int,int,int);
int main(void)
printf("終點座標\n");
scanf("%d %d",&end_r,&end_c);
if(maze[end_r][end_c]!=0)
maze[start_r][start_c]=-2;
print_maze();
dfs(start_r,start_c,end_r,end_c);
return 0;
}void print_maze()
printf("\n");
}printf("\n");
return;
}void print_path(int start_r,int start_c)
return;
}int make_new_place(int place_r,int place_c,int director)
if(maze[new_r][new_c]==0)
ret_place=new_r*col+new_c;
if(maze[new_r][new_c]==-2)
ret_place=-2;
return ret_place;
}bool dfs(int start_r,int start_c,int end_r,int end_c)
int new_p;
for(i=0;i<4;i++)
}return result;
}騎士遍歷問題
即設定乙個棋盤,設定乙個起點,讓中國象棋中的馬遍歷整個棋盤。
我的做法是 當馬遍歷整個棋盤時因為不能重複走,則走的次數等於棋盤格仔數-1.
當達到這個條件輸出結果。
其他與迷宮問題類似
注意:可以跟迷宮問題一樣,設定乙個陣列,陣列大小與棋盤一樣,不初始化的話每個值為0,走過乙個點,將這個點設定乙個值。這樣使這個點不會再被走過。還可以走過乙個點後,將這個點標記,利用陣列標記為1,。兩種方法原理類似。馬有8種可能的方向,注意約束。
#include
#include
#include
#define n 20
int len;
int path_len=0;
int a_mark[n][n];
int solution=0;
int path[n*n];
void mark(int);
void unmark(int);
void print_path();
int make_new_place(int,int,int);
bool dfs(int,int);
int main(void)
bool dfs(int start_r,int start_c)
else}}
return result;
}int make_new_place(int start_r,int start_c,int i)
if(new_r>=0&&new_r=0&&new_c(%d %d)",s,j);
}printf("\n");
}延伸一下,若要求出兩點最短的路徑。
此時結束條件設定為起始點與終點相同。若要輸出最短路徑,意思是要保留上一次路徑的資料。我設定了乙個陣列保留每種解法所需要的步數。如果新的步數更小則將此時的最短路徑重新整理,若新的步數更大,則替換,使此時的步數最小。
#include
#include
#define n 51
#define m 1000
int len;
int pathlen=0;
int mark[n][n];
int path[n*n];
int best_path[n*n];
int m[m];
int solution=0;
bool dfs(int,int,int,int);
void print_path(int);
void print_best(int);
int make_new_place(int,int,int);
int main(void)
printf("\n");
return 0;
}bool dfs(int start_r,int start_c,int end_r,int end_c)
int i;
for(i=0;i<8;i++)
}return result;
}void print_path(int limit)
printf("\n");
if(solution==1)
return;
}void print_best(int limit)
裝箱問題及延伸
有乙個箱子容量為v 正整數,o v 20000 同時有n個物品 30 每個物品有乙個體積 o 正整數 10000 要求從 n 個物品中,任取若千個裝入箱內。方法1 設 f i 為不超過 i 的最大值,就可以看做揹包。即費用等於價值。得 f j max includeusing namespace s...
struct sockaddr定義及延伸
跟蹤看一下 strcut sockaddr 是怎麼定義的,這個定義在 usr include bits socket.h裡 引用 struct sockaddr 由上可見,sockaddr 結構體的第乙個成員是乙個巨集定義,再來看一下這個巨集定義 在 usr include bits sockadd...
從微控制器角度看堆疊及部分延伸問題
本文章為網路資源摘抄與總結,能力有限,有錯誤與漏洞希望大佬們給予提示或幫助,感謝 一 堆疊的相關概念 1 棧區 stack 由編譯器自動分配和釋放,存放函式的引數值 區域性變數的值等,其操作方式類似 於資料結構中的棧。2 堆區 heap 一般由程式設計師分配和釋放,若程式設計師不釋放,程式結束時可能...