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;
}
发布了78 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Meulsama/article/details/104970709
今日推荐