POJ 1872 A Dicey Problem

题目大意:给一个由数字组成的地图和一个设定好的骰子。骰子被放在一个地点,告诉你地点的坐标和此时骰子的上面和前面。要求是当骰子的上面的值等于骰子周围点的值 或者 周围有一个-1的值的时候才能把骰子移动到那边。最后要求出骰子返回初始位置的路径。

思路:首先骰子是给定的,所以知道上面和正面的时候我们就能知道骰子的各个面了,因为骰子的正对的两个面的值之和是7.。然后用一个4维的数组判重,一二维度记录坐标。第三维记录上面的值,第四维记录正面的值。然后进行BFS。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>

using namespace std;

struct node
{
    int x,y;
    int up;
    int f;
    vector <int> path;
};

int map[12][12];
int v[12][12][7][7];
int state[7][7];
int dx[] = {-1,1,0,0};  //题目要求的是按上下左右的最小字典序
int dy[] = {0,0,-1,1};
int n,m;
int stx,sty;   

void bfs(node t)
{
    queue<node>Q;
    node w,e;
    Q.push(t);

    while(!Q.empty())
    {
        w=Q.front();
        Q.pop();

        for(int k=0;k<4;k++)
        {
            e=w;
            int x=e.x+dx[k];
            int y=e.y+dy[k];
            int tf=e.f,tup=e.up;

            if(k==0){tf=7-e.up;tup=e.f;}//往上翻
            else if(k==1){tup=7-e.f;tf=e.up;} //往下翻
            else if(k==2)tup=state[e.up][e.f];//....
            else tup=7-state[e.up][e.f]; //....

            if(map[x][y]!=0 && (map[x][y]==e.up || map[x][y]==-1) && v[x][y][tup][tf]==0)
            {
                //printf("x = %d y = %d up = %d f = %d\n",x,y,tup,tf);
                v[x][y][tup][tf]=1;
                e.x=x;
                e.y=y;
                e.f=tf;
                e.up=tup;
                e.path.push_back(x);
                e.path.push_back(y);
                Q.push(e);

                if(x==stx && y==sty)
                {
                   // printf("  ");
                    for(int s=0;s<e.path.size()/2;s++)  //注意打印的格式控制
                    {
                        if(s%9==0)printf("  ");
                        if(s!=e.path.size()/2-1)printf("(%d,%d),",e.path[s*2],e.path[s*2+1]);
                        else printf("(%d,%d)",e.path[s*2],e.path[s*2+1]);

                        if((s+1)%9==0 && s!=e.path.size()/2-1)printf("\n");

                    }
                    return;
                }
            }
        }
    }
    printf("  No Solution Possible");
}


int main()
{
    memset(state,0,sizeof(state));
    state[1][2]=3;state[1][3]=5;state[1][4]=2;state[1][5]=4;   //首先处理骰子的状态
    state[2][1]=4;state[2][4]=6;state[2][6]=3;state[2][3]=1;
    state[3][1]=2;state[3][2]=6;state[3][6]=5;state[3][5]=1;
    state[4][1]=5;state[4][5]=6;state[4][6]=2;state[4][2]=1;
    state[5][1]=3;state[5][3]=6;state[5][6]=4;state[5][4]=1;
    state[6][2]=4;state[6][4]=5;state[6][5]=3;state[6][3]=2;

    string name;
    node w;
    while(cin>>name)
    {
        if(name=="END")break;

        memset(map,0,sizeof(map));
        memset(v,0,sizeof(v));
        w.path.clear();
        scanf("%d%d%d%d%d%d",&n,&m,&w.x,&w.y,&w.up,&w.f);

        stx=w.x;
        sty=w.y;

        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        scanf("%d",&map[i][j]);

        w.path.push_back(w.x);
        w.path.push_back(w.y);

        cout<<name<<endl;

        bfs(w);
        putchar(10);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值