八数码难题

【题目描述】

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

【输入描述】

输入初试状态,一行九个数字,空格用0表示。

【输出描述】

只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)。

【样例输入】

283104765

【样例输出】

4

 

IDA*算法:

源代码:

#include<cstdio>
#include<algorithm>
using namespace std;
int Goal[3][3]={{1,2,3},
                {8,0,4},
                {7,6,5}};
int x[4]={1,-1,0,0},y[4]={0,0,-1,1};
int X,Y,K,i[3][3];
bool Flag(0);
bool Check()
{
    for (int a=0;a<3;a++)
      for (int b=0;b<3;b++)
          if (i[a][b]!=Goal[a][b])
            return false;
    return true;
}
bool Eva(int t,int i[3][3])
{
    int num(0);
    for (int a=0;a<3;a++)
      for (int b=0;b<3;b++)
        if (i[a][b]!=Goal[a][b])
        {
            num++;
              if (num+t>K)
                return false;
        }
    return true;
}
void Solve(int t,int i[3][3],int X,int Y,int xxx,int yyy)
{
    if (t==K)
    {
        if (Check())
          Flag=true;
          return;
    }
    if (Flag)
      return;
    for (int a=0;a<4;a++)
    {
        int t1=X+x[a],t2=Y+y[a];
          if (t1<0||t1>2||t2<0||t2>2||(t1==xxx&&t2==yyy))
            continue;
          swap(i[X][Y],i[t1][t2]);
          if (Eva(t,i))
            Solve(t+1,i,t1,t2,X,Y);
          swap(i[X][Y],i[t1][t2]);
    }
}
int main()
{
    for (int a=0;a<3;a++)
      for (int b=0;b<3;b++)
      {
          char t;
        scanf("%c",&t);
        i[a][b]=t-'0';
        if (!i[a][b])
        {
            X=a;
            Y=b;
        }
      }
    while (!Flag)
    {
        K++;
          Solve(0,i,X,Y,X,Y);
    }
    printf("%d",K);
    return 0;
}

 

 

双向广搜:

 

posted @ 2016-06-11 21:31  前前前世。  阅读(257)  评论(0编辑  收藏  举报