POJ 1175 連連看(BFS 記錄轉彎次數)

2021-09-28 21:29:15 字數 1801 閱讀 3226

連連看,並且連線不能從外面繞過去,第一反應是bfs。

樣例過了以為挺簡單的,wa了兩個小時。。。

1、首先,一上來我們可以先排除一些情況,起始或目標為0、起始和目標不相等、起始和目標在同一位置,這三種情況直接no

2、int dir;用來記錄每一點的方向,0, 1, 2, 3分別對應上下左右

3、再用int change;記錄每一點的轉彎次數,int val[maxn][maxn];記錄每一點的最小轉彎數,初始為無窮大 。兩者配合使用達到判重/剪枝的目的。

之前,我們通常用乙個inq陣列來記錄結點是否入過佇列來判重,但這題如果仍然採用inq陣列不太好處理,因為每個結點經過上下左右四個方向得到四個新結點的入隊順序對最後結果會有影響(具體分析見下圖),所以用val[maxn][maxn]記錄每一點的最小轉彎數,與change比較,保證當前轉彎次數最少的結點入隊。

如果不判重會不會往回搜尋啊。確實,就像上圖虛線所示,但不必但心,往回走他們的change將超過2,我們可以用if(tmp.change>2) continue;剪去。

4、最後乙個目標結點也要入隊。

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const

int mod =

10000007

;const

int inf =

0x3f3f3f3f

;//const double pi = acos(-1.0);

const

int maxn =

1010

;int row, col, t;

int x1,y1,x2,y2;

int x[4]

=;//上下左右

int y[4]

=;int a[maxn]

[maxn]

;int val[maxn]

[maxn]

;//記錄每一點的最小轉彎數,初始為無窮大

struct node start, top, tmp;

bool

bfs(

)else

//否則,change加1

if(tmp.change>2)

continue;if

(tmp.change<=val[newx]

[newy]

)//保證轉彎次數最少,等號不能漏 }}

}return

false;}

intmain()

if(bfs())

printf

("yes\n");

else

printf

("no\n");

}}return0;

}

搜尋 HDU1175 連連看

題目 分析 這道題看到的第一反應應該就是bfs或者dfs,裸的dfs bfs顯然會tle,所以我就想用a 不過好像並不好寫啟發函式。列舉步數不行,就列舉邊吧。因為允許有兩次轉折,所以最多有三條邊列舉中間的一條邊,然後進行check,這道題只用了兩個for迴圈就ac了。include include ...

HDU1175連連看 廣度優先搜尋BFS

1 include 2 include 3 include 4 include 5 include 6 include 7 include 8 include 9 include 10 include 11 include 12 include 13 include 14 using namespa...

hdoj 1175 連連看 dfs 剪枝

題目大意 題目給出一副連連看的圖形,其中0代表沒有物品,其餘數字代表該位置的物品,規定,每次消除所經過的路徑不能超過兩次專向。另外,不能在圖外進行轉向。問,對於q個詢問,是否能夠消除。每乙個詢問都是對於初始圖而言的,解題思路 dfs 剪枝。其實沒什麼好說的,有幾個要注意的地方,第乙個是判重,第二個是...