zoukankan      html  css  js  c++  java
  • Vijos 八数码问题

    背景

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

    描述

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

    格式

    输入格式

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

    输出格式

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

    样例1

    样例输入1

    283104765
    

    样例输出1

    4



      1 /*
      2     搜索过程没什么好说的
      3     我只想说一下hash
      4     这个判重好坑 数据太细了!
      5     只好用康拓展开 
      6 */
      7 #include<cstdio>
      8 #include<cstring> 
      9 #include<iostream>
     10 #define MAXN 1000010 
     11 
     12 using namespace std;
     13 
     14 int map[3][3],x,y,head,tail;
     15 
     16 int _x[4]={0,1,0,-1};
     17 int _y[4]={1,0,-1,0};
     18 
     19 struct node {
     20     int m[3][3];
     21 };
     22 node e[MAXN];
     23 
     24 char s[10];
     25 
     26 int step[MAXN];
     27 
     28 bool _hash[67338000],flag;
     29 
     30 inline void _pre() {
     31     string ss="123804765";
     32     for(int i=0;i<9;i++) {
     33         map[x][y]=ss[i]-48;
     34         y++;
     35         if(y==3) x++,y=0;
     36     }
     37     x=0;y=0;
     38     return;
     39 }
     40 
     41 inline bool __hash() {
     42     int _Inr=0,k=1,t=1;
     43     for(int i=0;i<3;i++)
     44       for(int j=0;j<3;j++) {
     45           _Inr+=e[tail].m[i][j]*k;
     46           t++,k*=t;
     47       }
     48     //_Inr%=373897779;
     49     if(!_hash[_Inr]) {
     50         _hash[_Inr]=true;
     51         return true;
     52     }
     53     return false;
     54 }
     55 
     56 inline bool pd(int i,int j) {
     57     return i>=0&&j>=0&&i<3&&j<3;
     58 }
     59 
     60 inline bool check() {
     61     for(int i=0;i<3;i++)
     62       for(int j=0;j<3;j++) 
     63         if(e[tail].m[i][j]!=map[i][j]) return false;
     64     return true;
     65 }
     66 
     67 inline void move(int p,int q) {
     68     int xx,yy; 
     69     for(int i=0;i<4;i++) {
     70         xx=p+_x[i];
     71         yy=q+_y[i];
     72         if(pd(xx,yy)) {
     73             for(int a=0;a<3;a++)
     74               for(int b=0;b<3;b++)
     75                 e[tail].m[a][b]=e[head].m[a][b];
     76             swap(e[tail].m[p][q],e[tail].m[xx][yy]);
     77             step[tail]=step[head]+1;
     78             if(check()) {
     79                 printf("%d
    ",step[tail]);
     80                 flag=true;
     81                 return;
     82             }
     83             if(__hash()) tail++;
     84         }
     85     }
     86 }
     87 
     88 inline void search() {
     89     while(head<tail) {
     90         for(int i=0;i<3;i++)
     91           for(int j=0;j<3;j++) {
     92               if(e[head].m[i][j]==0) move(i,j);
     93               if(flag) return;
     94           }
     95         head++;
     96     }
     97 }
     98 
     99 int main() {
    100     _pre();
    101     scanf("%s",s);
    102     for(int i=0;i<strlen(s);i++) {
    103         e[0].m[x][y]=s[i]-48;
    104         y++;
    105         if(y==3) y=0,x++;
    106     }
    107     tail++;
    108     search();
    109     return 0;
    110 }
    代码


    作者:乌鸦坐飞机
    出处:http://www.cnblogs.com/whistle13326/
    新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

     
  • 相关阅读:
    [转]C#读写app.config中的数据
    [转]DirectoryEntry的应用
    js读取xml文档,并实现简单分页
    [转]写给想要做产品经理的同学
    《算法导论》(第二章)算法入门
    《算法导论》中伪代码的约定
    HDU ACM 1284 钱币兑换问题
    《算法导论》(第一部分)(第一章)
    HDU ACM 4554 叛逆的小明
    HDU ACM 1002 A + B Problem II
  • 原文地址:https://www.cnblogs.com/whistle13326/p/7123628.html
Copyright © 2011-2022 走看看