zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    _bzoj1061 [Noi2008]志愿者招募【最小费用最大流】
    _bzoj2243 [SDOI2011]染色【树链剖分】
    _bzoj1013 [JSOI2008]球形空间产生器sphere【高斯消元】
    _bzoj1002 [FJOI2007]轮状病毒【瞎搞】
    leetcode 273 Integer to English Words
    leetcode 12 Integer to Roman
    leetcode 1071 Greatest Common Divisor of Strings
    lc6 ZigZag Conversion
    lc13 Roman to Integer
    leetcode 171 Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/fujudge/p/7597700.html
Copyright © 2011-2022 走看看