HDU - 1043 Eight(广搜+打表)

Description

The 15-puzzle has been around for over 100 years; even if you don’t know it by that name, you’ve seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let’s call the missing tile ‘x’; the object of the puzzle is to arrange the tiles so that they are ordered as:

1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 x

where the only legal operation is to exchange ‘x’ with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle:

1 2 3 4
5 6 7 8
9 x 10 12
13 14 11 15
r->
1 2 3 4
5 6 7 8
9 10 x 12
13 14 11 15
d->
1 2 3 4
5 6 7 8
9 10 11 12
13 14 x 15
r->
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 x
The letters in the previous row indicate which neighbor of the ‘x’ tile is swapped with the ‘x’ tile at each step; legal values are ‘r’,‘l’,‘u’ and ‘d’, for right, left, up, and down, respectively.

Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing ‘x’ tile, of course).

In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three arrangement.

Input

You will receive, several descriptions of configuration of the 8 puzzle. One description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus ‘x’. For example, this puzzle

1 2 3
x 4 6
7 5 8

is described by this list:

1 2 3 x 4 6 7 5 8

Output

You will print to standard output either the word ``unsolvable’’, if the puzzle has no solution, or a string consisting entirely of the letters ‘r’, ‘l’, ‘u’ and ‘d’ that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line. Do not print a blank line between cases.

Sample input

2 3 4 1 5 x 7 6 8

Sample output

ullddrurdllurdruldr

分析

x 可以与它 上 下 左 右 数字交换位置,搜索是否能得到 “”12345678x“”, 找到则输出 交换过程 ,找不到 则输出 “unsolvable”。

把 x 当成 0 看待,所以有每个位置有九种可能,共九个位置,无法用普通数组标记。

可以用 map<int,string> 这种形式的map容器进行表示,从初始状态到达 int 状态经历的路径string。

如果,根据题目给定的初始状态去找“”123456780“”,超时。因为,需要找的最终状态是“”123456780“”,
所以,把“123456780”当成初状态,去找所能到达的状态,只需要bfs()一次,把所有能到达的状态打一次表,对于每次询问,查找int键值是否存在,存在则输出是反向输出,u和d,l和r交换输出,不存在,unsolvable。

代码

// An highlighted block
var foo = 'bar';

#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;

map<int,string>v;
struct node
{
  string a,s;
  int x;
};

void bfs()
{
  node now,net;
  queue<node>Q;
  now.a="123456780";
  now.s="";
  now.x=8;
  v[123456780]="";
  Q.push(now);
  while(!Q.empty())
  {
      now=Q.front();
      Q.pop();
      for(int i=1; i<=4; i++)
      {
          char p;
          int fg=0,dx=now.x;
          if(i==1&&now.x+3<=8)
              dx=now.x+3,p='u',fg=1;
          else if(i==2&&now.x-3>=0)
              dx=now.x-3,p='d',fg=1;
          else if(i==3&&now.x%3>=1)
              dx=now.x-1,p='r',fg=1;
          else if(i==4&&now.x%3<=1)
              dx=now.x+1,p='l',fg=1;

          if(!fg) continue;

          net=now;
          swap(net.a[now.x],net.a[dx]);

          int d=0;
          for(int j=0; j<9; j++)
              d=d*10+net.a[j]-'0';

          if(v.find(d)==v.end())
          {
              net.s+=p;
              net.x=dx;
              v[d]=net.s;
              Q.push(net);
          }
      }
  }
}

int main()
{
  bfs();
  char c[5];
  string c1;
  while(~scanf("%s",c))
  {
      int i,d=0;
      if(c[0]=='x')
          d=d*10+0;
      else
          d=d*10+c[0]-'0';
      for(i=1; i<9; i++)
      {
          scanf("%s",c);
          if(c[0]=='x')
              d=d*10+0;
          else
              d=d*10+c[0]-'0';
      }
      if(v.find(d)!=v.end())
      {
          c1=v[d];
          for(i=c1.size()-1; i>=0; i--)
              cout<<c1[i];
          cout<<endl;
      }
      else
          cout<<"unsolvable"<<endl;
  }
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值