• codevs1225: 八数码难题


    题目描述 Description

    Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.
    问题描述

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

    输入描述 Input Description

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

    输出描述 Output Description

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

    样例输入 Sample Input

    283104765

    样例输出 Sample Output

    4

    题解

    写过poj和hdu的八数码以后写这道题处理起来就轻松多了。。裸题没啥说的,注意一下估价函数不计算0到目标位置的曼哈顿距离,否则是错误的(有兴趣的自己证明一下)。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 int dx[5]={0,0,1,-1},dy[5]={1,-1,0,0};
     6 int lastx[10]={1,0,0,0,1,2,2,2,1},lasty[10]={1,0,1,2,2,2,1,0,0};
     7 int a[15],deep;
     8 bool Ok(int x,int y)
     9 {
    10     if(x<0||x>2||y<0||y>2)return false;
    11     return true;
    12 }
    13 bool Nofa(int x,int y)
    14 {
    15     if(x>y)swap(x,y);
    16     if(x==0&&y==1)return false;
    17     if(x==2&&y==3)return false;
    18     return true;
    19 }
    20 void dfs(int step,int h,int dir,int now)
    21 {
    22     if(step+h>deep)return ;
    23     if(!h)
    24     {
    25         printf("%d",deep);
    26         exit(0);
    27     }
    28     int x=now/3;int y=now%3;
    29     for(int i=0 ; i<4 ; ++i )
    30     {
    31         int xx=x+dx[i];int yy=y+dy[i];
    32         if(Ok(xx,yy)&&Nofa(dir,i))
    33         {
    34             int zz=xx*3+yy;
    35             int ht=h-(abs(lastx[a[zz]]-xx)+abs(lasty[a[zz]]-yy))+(abs(lastx[a[zz]]-x)+abs(lasty[a[zz]]-y));
    36             swap(a[now],a[zz]);
    37             dfs(step+1,ht,i,zz);
    38             swap(a[now],a[zz]);
    39         }
    40     }
    41 }
    42 int Get()
    43 {
    44     int ret(0);
    45     for(int i=0 ; i<9 ; ++i)
    46     {
    47         if(a[i]==0)continue;
    48         int x=i/3;int y=i%3;
    49         ret+=abs(lastx[a[i]]-x)+abs(lasty[a[i]]-y);
    50     }
    51     return ret;
    52 }
    53 int main()
    54 {
    55     char str[15];
    56     int pos;
    57     scanf("%s",str);
    58     for(int i=0 ; i<9 ; ++i)
    59     {
    60         a[i]=str[i]-'0';
    61         if(!a[i])pos=i;
    62     }
    63     int h=Get();
    64     for( deep=0 ; ; deep++ )
    65         dfs(0,h,4,pos);
    66     return 0;
    67 }
  • 相关阅读:
    baidu 地图 鼠标移上显示标签 鼠标离开隐藏标签
    ci框架 用框架自带db 添加括号,比如 like 等等左右添加括号 解决办法
    layDate 闪现 循环一个以上会闪现
    typescript定义函数类型
    typescript中的类与接口的关系
    typescript中的类
    typescript中的接口
    mac 上配置 ssh 免密登录服务器 【非常简单】
    Go语言中的map(十一)
    Go语言中的切片(十)
  • 原文地址:https://www.cnblogs.com/fujudge/p/7597700.html
Copyright © 2020-2023  润新知