下载了一款推箱子小游戏,第13关的时候怎么也破不了最佳纪录(最少步数是9而我们最好的方案是10步),因为数据比较小(6*8的方阵),所以写了个BFS来找最短路。
游戏的目标是把小黄人推到黄色球,小绿人推到绿色球,有个限制是,小黄/绿人运动时会沿某一个方向一直走直到遇到边界或者障碍物,如果途中遇到传送带还会改变运动方向。

-------------------------------------------------------------------------------------------------------------------------------
每个状态转移的时候有4*2个选择。标记已经访问过的状态就好了。
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> Coord;
struct Status{
Coord y,g;
int step,fid,id;
Status(const Coord& y,const Coord& g,int step=0):y(y),g(g),step(step){fid = -1; id = 0;}
const Status& setId(int id,int fid){
this->id = id;
this->fid = fid;
return *this;
}
bool operator<(const Status& another) const { return step>another.step; }
int hash(){ return y.first*1000+y.second*100+g.first*10+g.second; }
friend ostream& operator<<(ostream& out,const Status& s){
return (out<<"yellow("<<s.y.first<<","<<s.y.second<<") green("<<s.g.first<<","<<s.g.second<<") step:"<<s.step);
}
};
Coord Y = {0,3};
Coord G = {5,2};
const int M = 6;
const int N = 8;
const int skip[4][2] = {{-1,0},{1,0},{0,1},{0,-1}};
bool vis[6868];
bool cango(int& x,int& y,int& dir,const Coord& another){
int tx = x + skip[dir][0];
int ty = y + skip[dir][1];
if(tx<0||ty<0||tx>=M||ty>=N) return false;
if(tx==another.first&&ty==another.second) return false;
x = tx,y = ty;
if(x==3&&y==2) dir=1;
if(x==4&&y==3) dir=0;
return true;
}
bool mov(Coord &a,const Coord& b,int dir){
int len = 0;
while(cango(a.first,a.second,dir,b)) len++;
return len>0;
}
//for print path
vector<Status> trace;
void print(const Status& node){
if(node.fid==-1){
std::cout<<node<<endl; return ;
}
print(trace[node.fid]);
std::cout<<node<<endl;
}
int main(){
Coord y = {0,5};
Coord g = {0,6};
Status start(y,g);
memset(vis,false,sizeof(vis));
priority_queue<Status> q;
q.push(start);
vis[start.hash()] = true;
trace.push_back(start);
while(q.size()){
Status cur = q.top(); q.pop();
if(cur.g==G&&cur.y==Y){
printf("step: %d
",cur.step);
print(cur);
break;
}
for(int i=0;i<4;i++){
Coord tmpy = cur.y;
Coord tmpg = cur.g;
if(mov(tmpy,cur.g,i)) {
Status next(tmpy,cur.g,cur.step+1);
if(!vis[next.hash()]){
trace.push_back(next.setId(trace.size(),cur.id));
q.push(next);
vis[next.hash()]=true;
}
}
if(mov(tmpg,cur.y,i)){
Status next(cur.y,tmpg,cur.step+1);
if(!vis[next.hash()]){
trace.push_back(next.setId(trace.size(),cur.id));
q.push(next);
vis[next.hash()]=true;
}
}
}
}
return 0;
}