題解 P1979 華容道 Noip2013

2022-06-20 06:12:11 字數 2580 閱讀 8368

小 b 最近迷上了華容道,可是他總是要花很長的時間才能完成一次。於是,他想到用程式設計來完成華容道:給定一種局面, 華容道是否根本就無法完成,如果能完成, 最少需要多少時間。

小 b 玩的華容道與經典的華容道遊戲略有不同,遊戲規則是這樣的

在乙個 \(n×mn \times mn×m\) 棋盤上有\(n \times m\) 個格仔,其中有且只有乙個格仔是空白的,其餘 \(n×m−1\) 個格仔上每個格仔上有乙個棋子,每個棋子的大小都是 \(1 \times 1\) 的;

有些棋子是固定的,有些棋子則是可以移動的;

任何與空白的格仔相鄰(有公共的邊)的格仔上的棋子都可以移動到空白格仔上。

遊戲的目的是把某個指定位置可以活動的棋子移動到目標位置。

給定乙個棋盤,遊戲可以玩 \(q\) 次,當然,每次棋盤上固定的格仔是不會變的, 但是棋盤上空白的格仔的初始位置、 指定的可移動的棋子的初始位置和目標位置卻可能不同。第 \(i\) 次玩的時候, 空白的格仔在第 \(exi\)​ 行第 \(eyi\) 列,指定的可移動棋子的初始位置為第 \(sxi\)​ 行第 \(syi\), \(txi\)​ 行第 \(tyi\)​ 列。

假設小 b 每秒鐘能進行一次移動棋子的操作,而其他操作的時間都可以忽略不計。請你告訴小 b 每一次遊戲所需要的最少時間,或者告訴他不可能完成遊戲。

3 4 2

0 1 1 1

0 1 1 0

0 1 0 0

3 2 1 2 2 2

1 2 2 2 3 2

2

-1

\(1 \leqslant x,y \leqslant 30\)

\(q \leqslant 500\)

看了乙個上午,果然是道day2t2,夠噁心!!!

寫篇題解記錄一下心酸的歷史。

這題考慮直接暴力的做法:

我們發現直接直接按照題意模擬有點麻煩,找找規律,靈機一動忽然想到如果空格子和別的格仔交換了位置,那麼他們是不是就是等於空格子的位置改變了?

廢話!那麼可以考慮移動空格子,讓他先去到棋子的其實位置旁邊然後一步步讓空格子帶著這個棋子走。具體沒寫過,可以參考這份**

brute force

inline void dfs (ll x, ll y, ll lx, ll ly, ll step) 

}

考慮正解,其實是剛剛已經差不多想出來了,發現剛剛其實就有一點浪費在把空格移到目標格仔的旁邊,那麼我們可不可以優化一下,直接把不同狀態之間連邊,設計乙個狀態 \(dis[i][j]\) 表示把空格移到 \(i,j\) 這個位置的最小步數,然後我們對於每個點,求出如果空格在他的旁邊的某個位置,並且不經過當前這個點到達這個點另乙個狀態的最小步數。

預處理完之後再用一遍bfs算出給出的空格到達給出棋子初始位置的旁邊的最小步數

最後用spfa算出空格到結束位置的旁邊的最小步數。

為什麼是結束旁邊? 因為空格在終點上時初始棋子才可以和他交換,交換後就到旁邊去了。

real solution

#includeusing namespace std;

#define a first

#define b second

int n,m,q,en;

const int n=35,m=5005,inf=0x3f3f3f3f;

const int dx=;

const int dy=;

int head[m],dis[n][n],d[m],g[n][n];

struct edge e[m<<3];

bool vis[m];

inline void addedge(int from,int to,int dis)

inline int getid(int x,int y)

inline void bfs(int ex,int ey,int sx,int sy,int dir)

}if(dir==4) return;

int id=getid(sx,sy);

for(int i=0;i<4;++i)

if(dis[sx+dx[i]][sy+dy[i]]>0)

addedge(id+dir,id+i,dis[sx+dx[i]][sy+dy[i]]);

addedge(id+dir,getid(ex,ey)+(dir+2)%4,1);

}inline void spfa(int sx,int sy)

}while(!q.empty())}}

}}int main()

while(q--)

bfs(ex,ey,sx,sy,4);

spfa(sx,sy);

int id=getid(tx,ty);

int ans=inf;

for(int i=0;i<4;++i) ans=min(ans,d[id+i]);

printf("%d\n",(ans==inf)?-1:ans);

}return 0;

}```【】

P1979 華容道 spfa題解

問題描述 小 b 最近迷上了華容道,可是他總是要花很長的時間才能完成一次。於是,他想到用程式設計來完成華容道 給定一種局面,華容道是否根本就無法完成,如果能完成,最少需要多少時間。小 b 玩的華容道與經典的華容道遊戲略有不同,遊戲規則是這樣的 在乙個 n m 棋盤上有 n m 個格仔,其中有且只有乙...

洛谷 P1979 華容道

題目描述 小 b 最近迷上了華容道,可是他總是要花很長的時間才能完成一次。於是,他想到用程式設計來完成華容道 給定一種局面,華容道是否根本就無法完成,如果能完成,最少需要多少時間。小 b 玩的華容道與經典的華容道遊戲略有不同,遊戲規則是這樣的 在乙個 n m 棋盤上有 n m 個格仔,其中有且只有乙...

洛谷P1979 華容道(70分 暴力)

問題描述 小 b 最近迷上了華容道,可是他總是要花很長的時間才能完成一次。於是,他想到用程式設計來完成華容道 給定一種局面,華容道是否根本就無法完成,如果能完成,最少需要多少時間。小 b 玩的華容道與經典的華容道遊戲略有不同,遊戲規則是這樣的 在乙個 n m 棋盤上有 n m 個格仔,其中有且只有乙...