URAL 1016 Cube on the Walk (SPFA+HASH)

很蛋疼的一题,一直在用广搜。先用了优先队列爆搜,发现不行,而且路径不好记录,然后开始用SPFA,然后对每个棋盘上的格子骰子的所有可能的状态HASH(8*8*6*4每个格子上的骰子都有24种),果断样例OK了,结果WA了。一直不知道怎么回事,结果搜一下,发现这个棋盘不是我想象中的棋盘(从上到下8->1,从左到右a->h),就修改了Rotate过了.....

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <map>
#include <set>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,102400000")
#define maxn 10
#define INF 1000000007
#define LL long long
#define ls rt<<1
#define rs rt<<1|1
int cube[6],st[6];///0-near, 1-far, 2-top, 3-right, 4-bottom and 5-left
struct Bnode
{
    int x,y;
    int sta[6];
    Bnode() {}
    Bnode(int _x,int _y)
    {
        x=_x;
        y=_y;
        for(int i=0; i<6; i++) sta[i]=st[i];
    }
} q[3605];

bool vis[4000];
int dis[4000],flag[10][10][6][6],pre[4000];
int qcnt;

struct Pnode
{
    int x,y;
} path[4000];
int pcnt;

int dx[]= {0,-1,0,1};
int dy[]= {-1,0,1,0};
int sx,sy,ex,ey;
///start point and end point
void rotate(int id,int sta[])
{
    if(id==2||id==0)
        st[1]=sta[1],st[0]=sta[0];
    if(id==1||id==3)
        st[3]=sta[3],st[5]=sta[5];

    if(id==2)
        st[2]=sta[5],st[5]=sta[4],st[4]=sta[3],st[3]=sta[2];
    else if(id==3)
        st[0]=sta[4],st[4]=sta[1],st[1]=sta[2],st[2]=sta[0];
    else if(id==0)
        st[2]=sta[3],st[3]=sta[4],st[4]=sta[5],st[5]=sta[2];
    else
        st[0]=sta[2],st[2]=sta[1],st[1]=sta[4],st[4]=sta[0];
}
void spfa(int x,int y)
{
    queue<Bnode>que;
    memset(vis,0,sizeof(vis));
    memset(flag,-1,sizeof(flag));
    memset(pre,-1,sizeof(pre));
    que.push(Bnode(x,y));
    vis[qcnt=0]=1;
    for(int i=0; i<4000; i++) dis[i]=INF;
    dis[0]=cube[4];
    while(!que.empty())
    {
        Bnode tmp=que.front();
        if(flag[tmp.x][tmp.y][tmp.sta[0]][tmp.sta[4]]==-1)
        {
            flag[tmp.x][tmp.y][tmp.sta[0]][tmp.sta[4]]=qcnt++;
            q[qcnt-1]=tmp;
        }
        int u=flag[tmp.x][tmp.y][tmp.sta[0]][tmp.sta[4]];
        que.pop();
        for(int i=0; i<4; i++)
        {
            int xt=tmp.x+dx[i];
            int yt=tmp.y+dy[i];
            if(xt>=1&&yt>=1&&xt<=8&&yt<=8)
            {
                rotate(i,tmp.sta);
                if(flag[xt][yt][st[0]][st[4]]==-1)
                {
                    flag[xt][yt][st[0]][st[4]]=qcnt++;
                    q[qcnt-1]=Bnode(xt,yt);
                }
                int v=flag[xt][yt][st[0]][st[4]];
                int dist=dis[u]+cube[st[4]];
                if(dist<dis[v])
                {
                    dis[v]=dist;
                    pre[v]=u;
                    if(!vis[v])
                    {
                        vis[v]=1;
                        que.push(q[v]);
                    }
                }
            }
        }
        vis[u]=0;
    }
}
int main()
{
    char a[3],b[3];
    while(~scanf("%s%s",a,b))
    {
        for(int i=0; i<6; i++)
        {
            scanf("%d",&cube[i]);
            st[i]=i;
        }
        sx=a[1]-'0',sy=a[0]-'a'+1;
        ex=b[1]-'0',ey=b[0]-'a'+1;
        spfa(sx,sy);
        int ans=INF;
        int st1,st2;
        for(int i=0; i<6; i++)
            for(int j=0; j<6; j++)
            {
                int u=flag[ex][ey][i][j];
                if(u!=-1&&dis[u]<ans)
                {
                    ans=dis[u];
                    st1=i,st2=j;
                }
            }
        printf("%d",ans);
        int xt=ex,yt=ey;
        int now=flag[xt][yt][st1][st2];
        pcnt=0;
        while(now!=-1)
        {
            path[pcnt].x=q[now].x;
            path[pcnt++].y=q[now].y;
            now=pre[now];
        }
        for(int i=pcnt-1; i>=0; i--)
            printf(" %c%d",(char)(path[i].y+'a'-1),path[i].x);
        puts("");
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值