
dy上的小游戏:将海绵宝宝翻转过来,从头朝下,变为,头朝上
问题普遍化
方块有六个面,记面和序号的映射:前1,后3,上2,下4,左6,右5, 初始时,输入地图大小n ,则地图为nxn 输入方块的初始位置和特殊图案所在的面,例如1 1 1 ,表示,方块在(1,1)位置,特殊的面在前面 输入方块需要达到的状态:例如1 1 5,表示,方块在(1,1)位置,特殊的面在右面 请程序输出,通过怎么样的翻转,能从初始状态达到目标状态,并输出翻转方法
对于举的例子,方法为:右,下,左,上
解决方法
思路:使用bfs求最短路径
注意点:1.将下一步的x,y变化量存为数组dx和dy,将下一步面朝的方向也用数组保存
2.将初始距离设置为很大的值(INF)
3.回溯路径:记录当前状态是从哪一状态转移而来的,记录转移的方向变化
#include <iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
const int maxn=105;
int dist[maxn][maxn][10],dir[maxn][maxn][10];
string dirmap[4]={"UP","DOWN","LEFT","RIGHT"};
int toface[5][10]={{0,2,3,4,1,5,6},{0,4,1,2,3,5,6},{0,1,6,3,5,2,4},{0,1,5,3,6,4,2}};
int dx[5]={0,0,-1,1},dy[5]={-1,1,0,0}; //0-上 1-下 2-左 3-右
int n,sx,sy,sp,tx,ty,tp;
struct state{
int x,y,p;
};
state from[maxn][maxn][10];
void bfs(){
memset(dist,0x3f,sizeof(dist));
dist[sx][sy][sp]=0;
queue<state> q;
q.push({sx,sy,sp});
while(q.size()){
state curs=q.front();
q.pop();
int x=curs.x,y=curs.y,p=curs.p;
if(x==tx && y==ty && p==tp) return;
//四个方向
for(int i=0;i<4;i++){
int nx=x+dx[i],ny=y+dy[i],np=toface[i][p];
if(nx<1 || nx>n || ny<1 || ny>n) continue;
q.push({nx,ny,np});
if(dist[x][y][p]+1<dist[nx][ny][np]){
dist[nx][ny][np]=dist[x][y][p]+1;
from[nx][ny][np]={x,y,p};
dir[nx][ny][np]=i;
}
}
}
}
void print_ans(int x,int y,int p){
if(x==sx && y==sy && p==sp) return;
print_ans(from[x][y][p].x,from[x][y][p].y,from[x][y][p].p);
cout<<dirmap[dir[x][y][p]]<<"\n";
}
int main() {
cout<<"Please Input the Map Size :";
cin>>n;
cout<<"Please Input the original position and direction: ";
cin>>sx>>sy>>sp;
cout<<"Please Input the Target values: ";
cin>>tx>>ty>>tp;
bfs();
print_ans(tx,ty,tp);
cout<<dist[tx][ty][tp];
return 0;
}
899

被折叠的 条评论
为什么被折叠?



