推箱子是一款經典的小遊戲。遊戲要求玩家將若干個箱子推到指定的位置,並以箱子移動次數最少做爲目標。 如今,咱們只須要考慮一個簡化的版本——只有一個箱子。對於一張給定的地圖,你須要判斷是否能夠將箱子推到目標位置,若是能夠,你還須要求出箱子最少的移動次數。數組
第一行有兩個用單個空格分隔的正整數 n , m ( n , m <= 100 ) ,表示輸入一張 n ∗ m 的地圖。 接下來 n 行,每行 m 個字母,字母分別是S, M, P, K, w,意義以下: S – 表示地圖中的牆 M – 表示玩家的初始位置 P – 表示箱子的初始位置 K- 表示箱子的目標位置 w – 表示地圖中的空格 M, P 和 K 在文件中只出現一次bash
若是箱子不能移動到目的位置,則輸出NO。post
若是箱子能移動到目的位置,則輸出最小的移動次數。優化
10 12
SSSSSSSSSSSS
SwwwwwwwSSSS
SwSSSSwwSSSS
SwSSSSwwSKSS
SwSSSSwwSwSS
SwwwwwPwwwww
SSSSSSSwSwSw
SSSSSSMwSwww
SSSSSSSSSSSS
SSSSSSSSSSSS
複製代碼
7
複製代碼
對於10%的數據: n=1或m=1ui
另10%的數據: n=5,m=100或n=100,m=5this
對於30% 的數據: n , m <= 50spa
對於 100 % 的數據: n , m <= 100code
題目大意大概就是這樣隊列
這個題也算是祖傳題了遊戲
上一屆的yveh學長當時這題就沒能作出來
點名批評某助教
大概講一下思路以及心路歷程
完整的代碼爲了(防止學弟學妹們借鑑,就不放了)
畢竟是祖傳題嘛!!
大概主要是對箱子進行bfs,而後每個點的狀態存儲當前的x,當前的y,當前的s(已走路程),還有上一次移動推過來的方向dir。
struct Node{
int x,y,s,dir;
};
複製代碼
而後每次對箱子bfs以前,都要對人進行bfs,看看能不能到箱子的四個位置,這時候上一次的dir就起做用了,能夠知道人的初始位置
因而我就這樣作了
不幸地TLE了
以後詢問了如下週圍同窗,而後優化了一些步驟的前後順序
So——速度大概快了負的百分之一吧!
我太難了
以後我就嘗試了一些黑科技
強行加上頭文件的O2O3Ofast優化之類的
可參考個人另外一篇文章
固然仍是沒用啦
以後班裏面的Hz同窗告訴我關於vis數組的判斷能夠優化的方法
like this:
屢次要用到vis[]時
能夠用把vis改爲int型,而後每次使用cnt++,若是cnt==vis[],說明這次已經遍歷到了;
反之,就讓vis[]=cnt;
複製代碼
速度好像是快了那麼一點點點點
然而仍是沒啥用
而後,而後……
又get到一個技巧,就是每次對人進行bfs的時候,不要bfs四個方向,而是一次bfs;
由於起點都是同樣的嘛,就是終點不太同樣
而後一次bfs全圖,再判斷這個點能不能到
理論上這個可讓程序快四倍
我又交了 ——————又T了
95分真的是氣死人
不過咱們班好多同窗都卡在了95分上面;
最後的最後
我由於之前一直用的是STL裏面的queue,畢竟我以爲更加方便,能夠用結構體
如今——————不得不改爲用數組表示隊列了
確實我知道這樣要快一點,可是基本上這要把整個程序都改一遍
唉 又能咋辦呢?
最後 費了好長一段時間,總算改完了
(若是不算以前的嘗試吧)1Y !!!
小做業以後————感嘆————STL害人!!!
真的不知道我何時又會真香
真香!
下面貼一點代碼
關於最後表示隊列的數組
int Q1[410000],Q2[410000],Q3[410000],Q4[410000],L,R;
int qx[410000],qy[410000],l,r;
複製代碼
箱子的bfs
void bfs(){
L=0,R=0;
for(int i=0;i<4;++i){
int nowx = th.x;
int nowy = th.y;
int nows=0;
int nowdir=i;
if(getbfs(my.x,my.y,nowx-dx[i],nowy-dy[i],th.x,th.y)){
R++;
Q1[R]=nowx,Q2[R]=nowy,Q3[R]=nows,Q4[R]=nowdir;
vis[nowdir][nowx][nowy]=true;
}
}
while(L<R){
L++;
int nowx=Q1[L];
int nowy=Q2[L];
int nows=Q3[L];
int nowdir=Q4[L];
BFS(nowx-dx[nowdir],nowy-dy[nowdir],nowx,nowy);
for(int i=0;i<4;++i){
int newsx=nowx+dx[i];
int newsy=nowy+dy[i];
int newss=nows+1;
int newsdir=i;
if(v[nowx-dx[i]][nowy-dy[i]]!=cnt) continue;
if(Map[newsx][newsy]=='S'||newsx<1||newsx>n||newsy<1||newsy>m||vis[i][newsx][newsy]==true) continue;
if(Map[newsx][newsy]=='K'){
flag=newss;
return;
}
R++;
Q1[R]=newsx,Q2[R]=newsy,Q3[R]=newss,Q4[R]=newsdir;
vis[i][newsx][newsy]=true;
}
}
return;
}
複製代碼
人的bfs
void BFS(const int &x,const int &y,const int &tx,const int &ty){
cnt++;
l=0,r=1;
qx[r]=x,qy[r]=y;
v[x][y]=cnt;
while(l<r){
l++;
int nowx=qx[l],nowy=qy[l];
for(int i=0;i<4;++i){
int newsx=nowx+dx[i];
int newsy=nowy+dy[i];
if(Map[newsx][newsy]=='S'||(newsx==tx&&newsy==ty)||newsx<1||newsx>n||newsy<1||newsy>m) continue;
if(v[newsx][newsy]==cnt) continue;
else{
v[newsx][newsy]=cnt;
r++;
qx[r]=newsx,qy[r]=newsy;
}
}
}
}
複製代碼
That's all.