UVA - 810 (A Dice problem 搜索)

这题有点坑,给的标准展开图中3和4的位置弄反了。

除了这个地方之外,只能说自己太笨了,这个题目已经明显提示一个骰子两个面足够确定骰子是唯一的。

所以状态就是坐标+顶面数字+前面数字。总共最多为row*column*24.

状态转移是四。很快就可以解出。

#include <set>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;

const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};
const int maxn = 11;
int L[7][4]={
{0},{3,2,4,5},
{1,3,6,4},
{1,5,6,2},
{1,2,6,5},
{1,4,6,3},
{3,5,4,2}
};
int to(int u,int f){
  for(int i=0;i<4;i++){
    if(L[u][i]==f)
        return L[u][(i+1)%4];
  }
}
int vis[maxn][maxn][7][7];
void rotate(int& u,int& f,int d){
   if(d==0){int tmp=u; u=f; f=7-tmp;}
   if(d==1){u=to(u,f);}
   if(d==2){int tmp=f; f=u; u=7-tmp;}
   if(d==3){u=7-to(u,f);}
}
struct node{
  int x,y,u,f;
  int pre;
  node(int x=0,int y=0,int u=0,int f=0,int pre=0):
      x(x),y(y),u(u),f(f),pre(pre){}
};
node sta[24*maxn*maxn];
int sx,sy,u,f,maze[maxn][maxn],n,m;
vector<node> ans;
void print_ans(int F){
  //cout<<F<<endl;
  ans.clear();
  ans.push_back(node(sx,sy,0,0,0));
  while(F!=-1){
     ans.push_back(sta[F]);
     F=sta[F].pre;
  }
  for(int j=ans.size()-1,i=0;j>=0;i++,j--){
    if(i%9==0) printf("  ");
    printf("(%d,%d)",ans[j].x,ans[j].y);
    if(i!=ans.size()-1) printf(",");
    if((i+1)%9==0||i==ans.size()-1) printf("\n");
  }
}
bool bfs(){
   sta[0]=node(sx,sy,u,f,-1);
   memset(vis,0,sizeof(vis));
   int front_=0,rear=1;
   while(front_<rear){
      node& u=sta[front_];
      for(int d=0;d<4;d++){
         int nx=u.x+dx[d],ny=u.y+dy[d];
         if(!(nx>=0&&ny>=0&&nx<=n&&ny<=m))
            continue;
         if(maze[nx][ny]!=-1&&maze[nx][ny]!=u.u)
            continue;
         if(nx==sx&&ny==sy){
            print_ans(front_);
            return true;
         }
         node v=u;
         v.x=nx; v.y=ny;
         rotate(v.u,v.f,d);
         if(!vis[v.x][v.y][v.u][v.f]){
            vis[v.x][v.y][v.u][v.f]=1;
            v.pre = front_;
            sta[rear++]=v;
         }
      }
     front_++;
   }
   return false;
}
char name[1000];
int main()
{
while(scanf("%s",name)!=EOF&&strcmp("END",name)!=0){
        scanf("%d %d %d %d %d %d",&n,&m,&sx,&sy,&u,&f);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            scanf("%d",&maze[i][j]);
        printf("%s\n",name);
        if(!bfs())
            printf("  No Solution Possible\n");
    }
}


你可能感兴趣的:(UVA - 810 (A Dice problem 搜索))