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. RabbitMQ八:交换机类型Exchange Types--Topic介绍

    前言 上一章节,我们说了两个类型,本章我们说一下其三:Topic Exchange Topic Exchange  Topic Exchange – 将路由键和某模式进行匹配.此时队列需要绑定要一个模 ...

  2. BBS项目总结

    数据库(Oracle): BBSUserid:主键username:用户名password:密码pic:头像 blobpagenum:每个人分页喜好数量,每页显示多少行 Article :ID:主键, ...

  3. Android获取本地相册图片、拍照获取图片

    需求:从本地相册找图片,或通过调用系统相机拍照得到图片. 容易出错的地方: 1,当我们指定了照片的uri路径,我们就不能通过data.getData();来获取uri,而应该直接拿到uri(用全局变量 ...

  4. 安卓&IOS 手机添加O365 邮箱账户

    手机添加O365 邮件账户 一.Android手机添加O365邮件账户 1. 找到手机上“电子邮件” 2. 打开设置 3. 点击添加账户 4. 选择“Exchange” 5. 输入O365的邮箱账户和 ...

  5. LR 两种录制:html与url

    一直在使用LR,对于Html_based script和Url-based script 两种录制方式之间,要如何选择,仍是一知半解.最近测试时遇到同样的业务功能,两种录制方式的脚本,单次执行时间差别 ...

  6. 算法之A星算法(寻路)

    1.启发式搜索:启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标.这样可以省略大量无谓的搜索路径,提高了效率.在启发式搜索中,对位置的估价是十分 ...

  7. Python3简明教程(十一)—— 类

    本节中将通过定义一些简单的 Python 类,来学习 Python 面向对象编程的基本概念. 定义类 在写你的第一个类之前,你应该知道它的语法.我们以下面这种方式定义类: class nameofth ...

  8. MySQL系列(三)--数据库结构优化

    良好的数据库逻辑设计和物理设计是数据库高性能的基础,所以对于数据库结构优化是很有必要的 数据库结构优化目的: 1.减少数据的冗余 2.尽量避免在数据插入.删除和更新异常 例如:有一张设计不得当的学生选 ...

  9. c++ cpp和hpp

    首先,我们可以将所有东西都放在一个.cpp文件内,编译器会将这个.cpp编译成.obj,即编译单元.一个程序可以由一个编译单元组成,也可以由多个编译单元组成.一个.cpp对应一个.obj,然后将所有的 ...

  10. Report Builder 打开报错

    提示:REP-0756:警告:找不到PL/SQL程序库’inv.pll’. 解决办法 处理:1.运行 ---输入REgedit ,在注册表内,查找注册表项Reports_path. 2.将下载的.pl ...