Aizu0121

Aizu0121

題意

在這裏插入圖片描述
t(<1000)組數據
0可以和上下左右四個位置交換
求最少多少步能變成圖d這種情況

思路

BFS求最短路徑

難點

正難則反:以往我BFS都是正着求,從輸入狀態到達理想狀態,然而這道題這麼做卻很麻煩,我們應該考慮從理想狀態到達輸入狀態,這完全不影響結果,反而有利於我們求解。
利用數據結構:這裏的輸入量很大,每次求一次BFS很麻煩,這種情況考慮BFS求所有情況,然後保存到map當中,直接輸出結果。
選用合理數據類型保存:我思考了很久該如何去保存這樣的數組,看到別人的解法是用string來表示整個數組的狀態,實在是秒。
新遇到的stl函數
getline(cin,str)可以接收一行string類型(包括空格) 所在庫<string>
s.erase(remove(s.begin(), s.end(), theCharacterNeedtoRemove), s.end()); 所在庫<algorithm>
上面這句話remove函數將string中第三個參數位置的字符移動到最後面,最後返回了去掉第三個參數的字符串的end()迭代器,利用他的返回值結合erase刪除特定字符。
remove()函數的複雜度O(26 * n) = O(n)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF  = 0x3f3f3f3f;
const ll  mod  = 1e9 + 7;
const ll  maxn = 1e6 + 5;
const int N = 10;

int a[N];
string s="01234567";
map<string,int>mp;
int dx[4]={1,-1,4,-4};

void bfs(){
	queue<string>q;
	q.push(s);
	while(!q.empty()){
		string p=q.front();
		q.pop();
		int pos=p.find('0');
		for(int i=0;i<4;i++){
			int tpos=pos+dx[i];
			if(tpos>=0 && tpos<=7 && (!((pos==3)&&i==0)) && (!((pos==4)&&i==1))){
				string k=p;
				swap(k[pos],k[tpos]);
				if(mp[k]==0 && k!="01234567"){
					mp[k]=mp[p]+1;
					q.push(k);
				}
			}
		}
	}
}

int main(){
	bfs();
	while(getline(cin,s)){
		s.erase(remove(s.begin(),s.end(),' '),s.end());
		printf("%d\n",mp[s]);
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章