題目鏈結
除去多次詢問不談,這道題大致的框架是非常明顯的搜尋。但是雖然是多次詢問,棋盤的狀態是不會變的,並且只有部分的位置是真正有價值的。那麼就可以考慮圖論建模,在這些有價值的狀態上跑從終態到末態的最短路。因為棋子要移動的時候,空白塊一定要移到它的周圍,所以我們可以為這種周圍的位置編號。f[x
][y]
[i
]f[x][y][i]
f[x][y
][i]
表示在點(x,
y)
(x, y)
(x,y
)的方向i(0
≤i≤3
)i(0\le i \le 3)
i(0≤i≤
3)上的位置的編號。這裡我們有兩個陣列表示方向的偏移量,不同的i
ii分別配對左、右、上、下:dx[
4]=0
,0,−
1,1,
dy[4
]=−1
,1,0
,0
dx[4]=,dy[4]=
dx[4]=
0,0,
−1,1
,dy[
4]=−
1,1,
0,0。這樣編號的好處是,ixo
r1
i \ xor\ 1
ixor
1即可表示相反的方向
點建好了,接下來考慮怎麼連邊。顯然的一點是,為了使目標棋子更快地前進,空白格移動到棋子旁的路上不應該與棋子發生交換。對於乙個在棋子旁邊的空白格,它有以下的選擇:
繞到棋子的另乙個方向上,使得棋子向該方向前進,即:$f[x][y][i]\to f[x][y][j](i\not= j) $
直接和棋子交換位置,讓棋子向原本的空白格的方向前進,即:f[x
][y]
[i]→
f[x+
dx[i
]][y
+dy[
i]][
ixor
1]
f[x][y][i]\to f[x+dx[i]][y+dy[i]][i \ xor \ 1]
f[x][y
][i]
→f[x
+dx[
i]][
y+dy
[i]]
[ixo
r1]由於第一種選擇不能受到各種元素限制,所以需要bfs來確定邊權。作完這些預處理之後,這些點之間就構成了乙個圖論模型。對於每次詢問,對移動的棋子周圍的4個位置做一次bfs,得到讓空白格(在不移動該棋子的情況下)移動到棋子四周的最小代價。再把這四個初狀態壓入佇列中,跑一遍spf
aspfa
spfa
,最後列舉末狀態取乙個dis
disdi
s的mi
nmin
min就是答案了
還有一些細節:
起點和終點相同時記得特判
正確估計模型中最多會有多少個點來開陣列
具體請結合**理解:
//從main開始看
#include
#include
const
int maxn=50;
const
int maxm=
1000000
;const
int inf=
0x3f3f3f3f
;int a[maxn]
[maxn]
,f[maxn]
[maxn][4
];int dx[4]
=,dy[4]
=;int head[maxn*maxn*4]
,to[maxm]
,nxt[maxm]
,val[maxm]
;int dis[maxn*maxn]
;int cnt,tot;
int n,m,q;
bool vis[maxn]
[maxn]
,inq[maxn*maxn]
;struct node
node
(int a,
int b,
int c)};
struct queue
void
push
(node x)
void
pop(
) node front()
bool
empty()
};//這兩個手寫佇列分別給bfs和spfa用= =,直接用stl也差不多的
struct que
void
push
(int x)
void
pop(
)int
front()
bool
empty()
};intmin
(int x,
int y)
bool
valid
(int x,
int y)
void
add(
int u,
int v,
int w)
intbfs
(int target_x,
int target_y,
int sx,
int sy,
int tx,
int ty)
}return inf;
}int
spfa
(int ex,
int ey,
int sx,
int sy,
int tx,
int ty)
while
(!q.
empty()
)}}int ans=inf;
for(
int i=
0;i<
4;i++
) ans=
min(ans, dis[f[tx]
[ty]
[i]]);
return ans==inf?-1
:ans;
}int
main()
for(
int x=
1;x<=n;x++
)for
(int y=
1;y<=m;y++
)for
(int i=
0;i<
4;i++
)for
(int j=
0;j<
4;j++
)//選擇1
for(
int x=
1;x<=n;x++
)for
(int y=
1;y<=m;y++
)for
(int i=
0;i<
4;i++
)while
(q--
)return0;
}
題解 P1979 華容道 Noip2013
小 b 最近迷上了華容道,可是他總是要花很長的時間才能完成一次。於是,他想到用程式設計來完成華容道 給定一種局面,華容道是否根本就無法完成,如果能完成,最少需要多少時間。小 b 玩的華容道與經典的華容道遊戲略有不同,遊戲規則是這樣的 在乙個 n mn times mn m 棋盤上有 n times ...
NOIP2013 華容道 廣搜 spfa
問題描述 小 b 最近迷上了華容道,可是他總是要花很長的時間才能完成一次。於是,他想到用程式設計來完成華容道 給定一種局面,華容道是否根本就無法完成,如果能完成,最少需要多少時間。小 b 玩的華容道與經典的華容道遊戲略有不同,遊戲規則是這樣的 在乙個 n m 棋盤上有 n m 個格仔,其中有且只有乙...
NOIP2013提高組day2 華容道
給出一張n m的棋盤,有一些點上有障礙物,其他點上都是棋子。給出q次詢問,每次詢問給出乙個空格,乙個目標棋子,乙個目標位置,每一步可以把乙個棋子移進空格,求把目標棋子移動到目標位置的最小步數。n,m 30,q 500 第一眼看到就知道是大暴力題,發現詢問次數少的時候一次bfs就解決了,那麼詢問多起來...