http://www.cnblogs.com/183zyz/archive/2011/08/12/2135827.html

#include<stdio.h>

#define N 363000

#include<string.h>

#include<queue>

using namespace std;

int visit[N];

char visit1[N];

int pre[N],st,a[10],end;

int dir[9]={1,1,2,6,24,120,720,5040,40320};

struct node {

 int ma[10];//记录状态

 int ans1;//记录状态值

 int x,f,g;

 bool operator <(const node &a)const {

  return a.f<f;

 }

};

int hash(int s[]) {//康拓展开逆序状态值

 int i,j,cnt,sum;

 sum=0;

 for(i=1;i<=9;i++) {

  cnt=0;

  for(j=1;j<i;j++)

   if(s[j]>s[i])cnt++;

   sum+=cnt*dir[i-1];

 }

 return sum;

}

int ABS(int x) {

 return x<0?(-x):x;

}

int h(int s[]) {//不算x时的曼哈顿距离

 int curx,cury,endx,endy,sum,i,ans;

 sum=0;

 for(i=1;i<=9;i++) {

  if(s[i]==9)continue;

  ans=s[i];

  curx=(i+2)/3;//算出当前的行

  cury=(i-1)%3+1;//算出当前的列

  endx=(ans+2)/3;//算出当前位置的值应该在的行

  endy=(ans-1)%3+1;//算出当前位置的值应该在的列

  sum=sum+ABS(curx-endx)+ABS(cury-endy);//算出距离

 }

 return sum;

}

void bfs() {

 int ans,i;

 priority_queue<node>q;

 node cur,next;

 cur.ans1=st=hash(a);//康拓展开查找状态

 visit[cur.ans1]=1;

 if(st==end)

  return;

 for(i=1;i<=9;i++) {//将当前的状态保存下来

  cur.ma[i]=a[i];

  if(a[i]==9)

   cur.x=i;

 }//记录当前的状态

 cur.g=0;//记录深度

 cur.f=h(a);//记录当前的f值

 q.push(cur);//入列

 while(!q.empty()) {

  cur=q.top();//比较f值的大小,选取小的

  q.pop();

  if((cur.x+2)/3!=1) {//向上翻

   next=cur;

   next.x=cur.x-3;//翻转后的位置

   next.ma[cur.x]=next.ma[next.x];//将上方的值存到空格中

   next.ma[next.x]=9;//将上方的值置为空格即‘9’;

   ans=hash(next.ma);//记录翻后的剩余状态

   if(!visit[ans]) {//判断翻转后的状态是否存在

    next.g++;

    next.f=next.g+h(next.ma);////估价函数

    visit[ans]=1;//表示状态值存在

    next.ans1=ans;//将下次状态值记录下来

    pre[ans]=cur.ans1;//将当前状态值记录下来

    visit1[ans]='u';//记录

    if(ans==end)return;

    q.push(next);

   }

  }

   if((cur.x+2)/3!=3) {//向下翻

   next=cur;

   next.x=cur.x+3;

   next.ma[cur.x]=next.ma[next.x];

   next.ma[next.x]=9;

   ans=hash(next.ma);

   if(!visit[ans]) {

    next.g++;

    next.f=next.g+h(next.ma);

    visit[ans]=1;

    next.ans1=ans;

    pre[ans]=cur.ans1;

    visit1[ans]='d';

    if(ans==end) return;

    q.push(next);

   }

  }

    if(cur.x%3!=1) {//向左翻

   next=cur;

   next.x=cur.x-1;

   next.ma[cur.x]=next.ma[next.x];

   next.ma[next.x]=9;

   ans=hash(next.ma);

   if(!visit[ans]) {

    next.g++;

    next.f=next.g+h(next.ma);

    visit[ans]=1;

    next.ans1=ans;

    pre[ans]=cur.ans1;

    visit1[ans]='l';

    if(ans==end)return;

    q.push(next);

   }

  }

     if(cur.x%3!=0) {//向右翻

   next=cur;

   next.x=cur.x+1;

   next.ma[cur.x]=next.ma[next.x];

   next.ma[next.x]=9;

   ans=hash(next.ma);

   if(!visit[ans]) {

    next.g++;

    next.f=next.g+h(next.ma);

    visit[ans]=1;

    next.ans1=ans;

    pre[ans]=cur.ans1;

    visit1[ans]='r';

    if(ans==end)return;

    q.push(next);

   }

  }

 }

}

int check(int s[]) {//剪枝判是否有解

 int i,j,cnt=0;

 for(i=1;i<=9;i++) {

  if(s[i]==9)

   continue;

  for(j=1;j<i;j++) {

   if(s[j]==9)

    continue;

   if(s[j]>s[i])

    cnt++;

  }

 }

 return cnt ;

}

int main() {

 int i,j,ans;

 char str[50];

 while(gets(str)) {

  ans=0;

  memset(visit,0,sizeof(visit));

  for(i=0;str[i];i++) {

   if(str[i]=='x')

    a[++ans]=9;

   else

    if(str[i]!=' ')

     a[++ans]=str[i]-'0';

  }//处理数据

    end=0;

    ans=check(a);//判断是否有解,即ans值必须是偶数才有结果

    if(ans%2) {

     printf("unsolvable\n");

     continue;

    }

    bfs();

    j=0;

    while(end!=st) {//找路径及处理方法

     str[j++]=visit1[end];

     end=pre[end];

    }

    for(i=j-1;i>=0;i--)//输出

     printf("%c",str[i]);

    printf("\n");

    }

 return 0;

}

hdu 1043 A*的更多相关文章

  1. POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)

    思路: 这三个题是一个比一个令人纠结呀. POJ-1077 爆搜可以过,94ms,注意不能用map就是了. #include<iostream> #include<stack> ...

  2. HDU 1043 Eight(八数码)

    HDU 1043 Eight(八数码) 00 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)   Problem Descr ...

  3. Eight POJ - 1077 HDU - 1043 八数码

    Eight POJ - 1077 HDU - 1043 八数码问题.用hash(康托展开)判重 bfs(TLE) #include<cstdio> #include<iostream ...

  4. HDU - 1043 - Eight / POJ - 1077 - Eight

    先上题目: Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  5. HDU 1043 Eight 八数码问题 A*算法(经典问题)

    HDU 1043 Eight 八数码问题(经典问题) 题意 经典问题,就不再进行解释了. 这里主要是给你一个状态,然后要你求其到达\(1,2,3,4,5,6,7,8,x\)的转移路径. 解题思路 这里 ...

  6. POJ 1077 && HDU 1043 Eight A*算法,bfs,康托展开,hash 难度:3

    http://poj.org/problem?id=1077 http://acm.hdu.edu.cn/showproblem.php?pid=1043 X=a[n]*(n-1)!+a[n-1]*( ...

  7. hdu 1043 Eight 经典八数码问题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 The 15-puzzle has been around for over 100 years ...

  8. hdu 1043 pku poj 1077 Eight (BFS + 康拓展开)

    http://acm.hdu.edu.cn/showproblem.php?pid=1043 http://poj.org/problem?id=1077 Eight Time Limit: 1000 ...

  9. HDU 1043 Eight(双向BFS+康托展开)

    http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用 ...

  10. HDU 1043 Eight(反向BFS+打表+康托展开)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 题目大意:传统八数码问题 解题思路:就是从“12345678x”这个终点状态开始反向BFS,将各 ...

随机推荐

  1. CF989C A Mist of Florescence

    思路: 有趣的构造题. 实现: #include <bits/stdc++.h> using namespace std; ][]; void fillin(int x, int y, c ...

  2. BZOJ1132: [POI2008]Tro(叉积 排序)

    题意 世上最良心题目描述qwq 平面上有N个点. 求出所有以这N个点为顶点的三角形的面积和 N<=3000 Sol 直接模拟是$n^3$的. 考虑先枚举一个$i$,那么我们要算的就是$\sum_ ...

  3. (转)IC设计完整流程及工具

    IC的设计过程可分为两个部分,分别为:前端设计(也称逻辑设计)和后端设计(也称物理设计),这两个部分并没有统一严格的界限,凡涉及到与工艺有关的设计可称为后端设计. 前端设计的主要流程: 1.规格制定 ...

  4. 时间插件-daterangepicker

    一款基于bootstrap的时间插件daterangepicker,顾名思义,主要用于时间区间选择,也可做单个时间选择 demo.1汉化版的一个时间选择案例 <!DOCTYPE html> ...

  5. JavaScript 的垃圾回收与内存泄露

    JavaScript采用垃圾自动回收机制,运行时环境会自动清理不再使用的内存,因此javascript无需像C++等语言一样手动释放无用内存. 在这之前先说一下垃圾回收的两种方式:引用计数与标记清除. ...

  6. 洛谷 P2604 [ZJOI2010]网络扩容

    题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. ...

  7. 30行代码消费腾讯人工智能开放平台提供的自然语言处理API

    腾讯人工智能AI开放平台上提供了很多免费的人工智能API,开发人员只需要一个QQ号就可以登录进去使用. 腾讯人工智能AI开放平台的地址:https://ai.qq.com/ 里面的好东西很多,以自然语 ...

  8. SQLite-删除查询

    SQLite -删除查询 SQLite DELETE查询用于从一个表删除现有记录.您可以使用WHERE子句删除查询删除选定行,否则所有记录将被删除. 语法: 删除查询的WHERE子句的基本语法如下: ...

  9. 初识WEBGL

    WEBGL (全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一 ...

  10. delphi并行压缩

    real case test MM parallel 4x scalable (i7 6700)(on the newer processors will be linear) I did a sma ...