44行代码AC_卡片换位(DFS变形题 视频讲解 )
勵志用盡量少的代碼做高效表達
問題描述
你玩過華容道的游戲嗎?
這是個類似的,但更簡單的游戲。
看下面 3 x 2 的格子
在其中放5張牌,其中A代表關羽,B代表張飛,* 代表士兵。
還有一個格子是空著的。
你可以把一張牌移動到相鄰的空格中去(對角不算相鄰)。
游戲的目標是:關羽和張飛交換位置,其它的牌隨便在哪里都可以。
輸入格式:
輸入兩行6個字符表示當前的局面
輸出格式:
一個整數(shù),表示最少多少步,才能把AB換位(其它牌位置隨意)
建議:這是一道BFS或DFS的變形題,對初學者來說還是有一點壓力的。如果你對搜索模板題還沒有掌握的話,那么請先比較熟練的掌握深搜、廣搜模板后再來嘗試解決。
- 搜索原理的視頻鏈接——>傳送門1
- 這是一道比較好的搜索模板練手題——>傳送門2
- 解析在這里——>傳送門3
思路分析
思路一:DFS
一開始以為需要“數(shù)字華容道”游戲的策略,或者需要一些技巧和推動, 也因此遲遲不敢動筆, 網(wǎng)搜后發(fā)現(xiàn),直接用DFS暴力推過去就可以:
以空格為起點, 上下左右探索, 每次回溯交換位置即可。(-_-|| 我還是不夠暴力)
有一點需要注意:
一般來講,我們做DFS的題時,都是習慣先判斷該步是否滿足條件,如果滿足,則對應的標記數(shù)組置1, 回溯,回溯結束后標記數(shù)組置0.
但對于本題來說,則需要用if循環(huán)判斷是否滿足條件,共有三種回溯的可能,這樣如果每種可能都重復以上的三步, 那么代碼就會冗余、易錯。
解決辦法是:對于每種可能的回溯情況, 無論是否符合,都進行回溯,在下一次回溯開始前統(tǒng)一判斷是否符合條件, 如果符合,則vis再置1。這樣不僅大大精簡了代碼,也提高了代碼的可讀性和效率
思路二:BFS
明天更新, 請持續(xù)關注~
一些小技巧:
1. 要使用getchar()處理輸入的字符,因為存在空格,scanf或cin無法識別,并且這樣的數(shù)也很難被存進數(shù)組里, 本解法沒有使用數(shù)組, 以幾個數(shù)的相對位置來模擬出數(shù)組, 請讀者細心體會。
2、涉及到坐標的運算時,用結構體模擬坐標求解,往往更為簡潔。
3、dfs函數(shù)中有一行代碼為:if(step > Min) return;在求最短路時加此代碼,可以很好的提高代碼效率
DFS解法代碼展示
#include<bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; int Min = inf; struct{int x, y; }a, b, k; int vis[3][3][3][3][3][3]; //標記數(shù)組,標記某點是否走過 int Next[4][2] = {{1,0}, {-1, 0}, {0, 1}, {0, -1}}; //分別代表向右,向左,向上,向下走 void dfs(int x1, int y1, int x2, int y2, int x, int y, int step) {if(step > Min) return; //提高效率,步數(shù)超過直接return; if(x1==b.x && y1==b.y && x2==a.x && y2==a.y) {Min = min(step, Min);return;}//先判斷越界if(x<0 || x>1 || y<0 || y>2) return;if(vis[x1][y1][x2][y2][x][y] == 1) return;vis[x1][y1][x2][y2][x][y] = 1; for(int i = 0; i < 4; i++) {int tx = x+Next[i][0];int ty = y+Next[i][1];if(tx==x1 && ty==y1) dfs(x, y, x2, y2, x1, y1, step+1);else if(tx==x2 && ty==y2) dfs(x1, y1, x, y, x2, y2, step+1);else dfs(x1, y1, x2, y2, tx, ty, step+1);}vis[x1][y1][x2][y2][x][y] = 0; }int main() {memset(vis, 0, sizeof(vis)); //輸入 for(int i = 0; i < 2 ; i++) {for(int j = 0; j < 3; j++) {char s = getchar();if(s=='A') { a.x=i; a.y=j; }if(s=='B') { b.x=i; b.y=j; }if(s==' ') { k.x=i; k.y=j; }}getchar();}//處理dfs(a.x, a.y, b.x, b.y, k.x, k.y,0); cout << Min << endl;return 0; }這世界就是,一些人總在晝夜不停的努力,而另外一些人,起床就發(fā)現(xiàn)世界已經(jīng)變了。 加油,陌生人!
總結
以上是生活随笔為你收集整理的44行代码AC_卡片换位(DFS变形题 视频讲解 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 视频讲解——零基础玩转微信小程序
- 下一篇: 27行代码AC_迷宫 2017年第八届蓝