SJTU T4143 推箱子

問題描述

推箱子是一款經典的小遊戲。遊戲要求玩家將若干個箱子推到指定的位置,並以箱子移動次數最少做爲目標。 如今,咱們只須要考慮一個簡化的版本——只有一個箱子。對於一張給定的地圖,你須要判斷是否能夠將箱子推到目標位置,若是能夠,你還須要求出箱子最少的移動次數。數組

輸入格式

第一行有兩個用單個空格分隔的正整數 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優化之類的

可參考個人另外一篇文章

卡常的編譯命令(含O2優化)

固然仍是沒用啦

以後班裏面的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.

相關文章
相關標籤/搜索