【题目链接】:http://hihocoder.com/problemset/problem/1312?sid=1092363

【题意】

【题解】

定义一个A*函数
f = step+val
这里的val是当前这个状态;每个点到目标状态的点的曼哈顿距离的绝对值;
(这个值肯定比真正需要花费的路程短)
step就为当前状态花费的步数;
把普通队列改成优先队列;
优先处理f值小的状态;
f值相同的,优先处理step值小的;
(也就是说f值大的不是不处理了,而是放到后面再处理)
这样就能较快地逼近目标状态了;
效果异常地棒
2s变成0.2s了!

【Number Of WA】

0

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)typedef pair<int,int> pii;
typedef pair<LL,LL> pll;const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const int pre[9][2] =
{{2,2},{0,0},{0,1},{0,2},{1,0},{1,1},{1,2},{2,0},{2,1}
};
const double pi = acos(-1.0);
const int N = 110;struct node
{int a[9],p,step,f;friend bool operator < (node x,node y){if (x.f==y.f){if (x.step==y.step)return true;elsereturn x.step>y.step;}elsereturn x.f>y.f;}
};node init;
priority_queue <node> dl;
map <int,int> dic;
int a[9],goal;
int cs[9] = {1,2,3,4,5,6,7,8,0};int has(int *a)
{int x = 0;rep1(i,0,8) x = x*10 + a[i];return x;
}int val(int *a)
{int ret = 0;rep1(i,0,8){int x = i/3,y = i%3;if (a[i]==0) continue;ret+=abs(pre[a[i]][0]-x)+abs(pre[a[i]][1]-y);}return ret;
}int bfs()
{while (!dl.empty()){int p = dl.top().p;int now = dl.top().step;node temp;rep1(i,0,8) temp.a[i] = dl.top().a[i];dl.pop();//上if (p>2){int tp = p-3;swap(temp.a[tp],temp.a[p]);int xzt = has(temp.a);if (xzt==goal) return now+1;if (dic.find(xzt)==dic.end()){dic[xzt] = now+1;temp.step = now+1;temp.p = tp;temp.f = temp.step+val(temp.a);dl.push(temp);}swap(temp.a[tp],temp.a[p]);}//下if (p<6){int tp = p+3;swap(temp.a[tp],temp.a[p]);int xzt = has(temp.a);if (xzt==goal) return now+1;if (dic.find(xzt)==dic.end()){dic[xzt] = now+1;temp.step = now+1;temp.p = tp;temp.f = temp.step+val(temp.a);dl.push(temp);}swap(temp.a[tp],temp.a[p]);}//左if (p%3!=0){int tp = p-1;swap(temp.a[tp],temp.a[p]);int xzt = has(temp.a);if (xzt==goal) return now+1;if (dic.find(xzt)==dic.end()){dic[xzt] = now+1;temp.step = now+1;temp.p = tp;temp.f = temp.step+val(temp.a);dl.push(temp);}swap(temp.a[tp],temp.a[p]);}//右if (p%3!=2){int tp = p+1;swap(temp.a[tp],temp.a[p]);int xzt = has(temp.a);if (xzt==goal) return now+1;if (dic.find(xzt)==dic.end()){dic[xzt] = now+1;temp.step = now+1;temp.p = tp;temp.f = temp.step+val(temp.a);dl.push(temp);}swap(temp.a[tp],temp.a[p]);}}return -1;
}int main()
{//freopen("F:\\rush.txt","r",stdin);ios::sync_with_stdio(false),cin.tie(0);//scanf,puts,printf not usegoal = has(cs);int t;cin >> t;while (t--){dic.clear();rep1(i,0,8){cin >> a[i];if (a[i]==0) init.p = i;}rep1(i,0,8) init.a[i] = a[i];init.step = 0,init.f = init.step+val(init.a);dic[has(init.a)] = 0;if (has(init.a)==goal){cout << 0 << endl;continue;}while (!dl.empty()) dl.pop();dl.push(init);int ans = bfs();if (ans==-1)cout <<"No Solution!"<<endl;elsecout << ans << endl;}return 0;
}

转载于:https://www.cnblogs.com/AWCXV/p/7626359.html

【hihocoder 1312】搜索三·启发式搜索(启发式搜索写法)相关推荐

  1. 【八数码问题】基于状态空间法的知识表示与状态搜索:无信息搜索(BFS/DFS) 启发式搜索(A*)

    前言 一.问题引入 二.状态空间法 1. 知识及其表示 2. 状态空间法定义 3. 问题求解 三.基于状态空间搜索法解决八数码问题 1. 八数码问题的知识表示 2. 状态空间图搜索 1. 无信息搜索 ...

  2. 搜索技术【启发式搜索】 - 简介 A* 算法 IDA*算法

    搜索技术[启发式搜索] - 简介 & A* 算法 & IDA*算法 尽管广度优先搜索.深度优先搜索加上有效的剪枝方法,可以解决很多问题,但这两种搜索都是盲目的,它们不管目标在哪里,只管 ...

  3. Vue移动端搜索页面的历史记录写法

    Vue移动端搜索页面的历史记录写法 前言 本文用于记录对于搜索页的历史记录的学习. 预览 先上两张图,分别为展示隐藏搜索列表和历史记录. html部分 <template><hips ...

  4. hihoCoder 1312:搜索三·启发式搜索(A* + 康托展开)

    题目链接 题意 中文题意 思路 做这题的前置技能学习 康托展开 这个东西我认为就是在排列组合问题上的Hash算法,可以压缩空间. A*搜索. 这里我使用了像k短路一样的做法,从最终状态倒回去预处理一遍 ...

  5. NR 小区搜索(三) SearchSpace0

    帖子微信更新会稍微快,可以关注同名modem协议笔记 之前讲了CORESET0 就是频域分布,那具体对应的时域位置是什么?那就需要结合SearchSpace0来确定. 具体的说CORESET0 描述的 ...

  6. [Elasticsearch2.x] 多字段搜索 (三) - multi_match查询和多数字段 译

    multi_match查询 multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询. NOTE 存在几种类型的multi_match查询,其中的3种正好和在"了解你的数据 ...

  7. WPF之Binding的三种简单写法

    环境 类代码 public class Person:INotifyPropertyChanged { private string name; public string Name { get { ...

  8. Verilog 三种计数器写法

    时钟周期 频率50MHz 倒数为1/(5*108)s=20ns,凑够一秒需要5 * 108个. ms us ns ps 0计数器设计要点 1 初始值 a) 复位值 b)每轮初始值 2 . 加1 条件 ...

  9. 地图兴趣点搜索三(ES相关性得分参数调整)

    1. 问题回顾 ​ 前面第一章,我们介绍了地图兴趣点检索的基本流程,以及如何用elasticsearch+ik搭建一个简单的demo.在运行demo时我们用"通州区万达广场"去搜索 ...

最新文章

  1. 迁移Win 2003 DHCP服务到2008R2
  2. Android开发RSS阅读器
  3. 网络推广——网络推广专员如何看待网站快照更新快慢问题?
  4. python super理解(二)
  5. iptables的增删改查
  6. MyBatis——动态SQL语句——if标签和where标签复合使用
  7. Mybatis中mapper接口里方法重载的实现
  8. 64位ubuntu kylin 16.04下制作tiny4412可用的SD启动卡
  9. 阿拉伯语排版设计_针对说阿拉伯语的用户的测试和设计
  10. 一款社区论坛小程序源码(修复登录图片发布上传问题)
  11. Shell 根据名称杀掉进程
  12. 【原创】关于nginx.pid丢失的解决办法
  13. 深职院计算机专业宿舍,深圳职业技术学院宿舍怎么样 住宿条件好不好
  14. 药品研发的项目化管理
  15. 关联分析---Apriori算法和FPGrowth算法挖掘规则计算频繁项间的置信度
  16. arcgis打开Excel文件显示没有注册类的解决方案
  17. 移动云API开放平台助力开发者驰骋云端
  18. springboot异常:Unrecognized field xxx , not marked as ignorable 问题
  19. 双麦阵列回音消除模块 F-23设计应用说明
  20. 简易处理字典MDX文件的方法

热门文章

  1. windows 禁用ipv6服务_Win10如何关闭IPV6?Win10禁用IPv6的方法
  2. 自己动手写java虚拟机_自己动手写操作系统(要了解的知识点)
  3. Flink-Java版单词计数(批处理流处理)
  4. 图像目标分割_6 Mask RCNN
  5. 笔记本电脑关机快捷键_2020年双十一值得入手的高性价比笔记本电脑外设推荐...
  6. Nodejs之http模块详解
  7. LeetCode 2133. 检查是否每一行每一列都包含全部整数
  8. LeetCode 2059. 转化数字的最小运算数(BFS)
  9. LeetCode 520. 检测大写字母
  10. NumPy快速入门--形状操作