翻转方块问题

78 阅读2分钟

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;
    }