Aizu0121
程序员文章站
2022-07-07 18:55:47
...
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;
}
推荐阅读