[BZOJ 1085] [SCOI2005] 骑士精神 [ IDA* 搜索 ]
题目链接 : BZOJ 1085
题目分析 :
本题中可能的状态会有 (2^24) * 25 种状态,需要使用优秀的搜索方式和一些优化技巧。
我使用的是 IDA* 搜索,从小到大枚举步数,每次 DFS 验证在当前枚举的步数之内能否到达目标状态。
如果不能到达,就枚举下一个步数,重新搜索,即使某些状态在之前的 DFS 中已经搜索过,我们仍然搜索。
并且在一次 DFS 中,我们不需要判定重复的状态。
在 IDA* 中,重要的剪枝优化是 估价函数 ,将一些不可能存在可行解的枝条剪掉。
如果估价函数写得高效,就能有极好的效果。我们写估价函数的原则是,绝对不能剪掉可能存在可行解的枝条。
因此,在预估需要步数时,应让估计值尽量接近实际步数,但一定不能大于实际需要的步数。
本题的一个很有效的估价函数是,比较当前状态的黑白骑士与目标状态的黑白骑士有多少不同,我们把这个值作为估价函数值,因为每一步最多将当前状态的一个骑士改变为与目标状态相同。但是应该注意的是,空格所在的格子不要算入其中。
代码如下:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm>using namespace std;const int MaxStep = 15; const int Dx[8] = {1, 1, -1, -1, 2, 2, -2, -2}, Dy[8] = {2, -2, 2, -2, 1, -1, 1, -1};int Te, Ans;char Str[6];struct ES {int num, pos;bool operator == (const ES &e) const {return (num == e.num) && (pos == e.pos);} } S, T;inline bool Inside(int x, int y) {if (x < 0 || x > 4) return false;if (y < 0 || y > 4) return false;return true; }void Print(ES x) {for (int i = 0; i < 5; ++i) {for (int j = 0; j < 5; ++j) {if (x.pos == (i * 5 + j)) printf("*");else {if (x.num & (1 << (i * 5 + j))) printf("1");else printf("0");}}printf("\n");} }inline int Expect(ES x) {int Temp, Cnt;Temp = x.num ^ T.num;Cnt = 0;if (x.pos != T.pos) {if (Temp & (1 << T.pos)) --Cnt;if (Temp & (1 << x.pos)) --Cnt;}while (Temp) {++Cnt;Temp -= Temp & -Temp;}return Cnt; }bool DFS(ES Now, int Step, int Limit) {if (Now == T) return true;if (Step == Limit) return false;if (Expect(Now) > Limit - Step) return false;int x, y, xx, yy;ES Next;x = Now.pos / 5; y = Now.pos % 5;for (int i = 0; i < 8; i++) {xx = x + Dx[i]; yy = y + Dy[i];if (!Inside(xx, yy)) continue;Next = Now; Next.pos = xx * 5 + yy;Next.num &= (1 << 25) - 1 - (1 << (xx * 5 + yy));if (Now.num & (1 << (xx * 5 + yy))) Next.num |= (1 << (x * 5 + y)); if (DFS(Next, Step + 1, Limit)) return true;}return false; }int IDAStar(ES S) {if (S == T) return 0;for (int i = 1; i <= MaxStep; ++i) if (DFS(S, 0, i)) return i;return -1; }int main() {scanf("%d", &Te);T.num = 549855; T.pos = 12;for (int Case = 1; Case <= Te; ++Case) {S.num = 0;for (int i = 0; i < 5; ++i) {scanf("%s", Str);for (int j = 0; j < 5; ++j) {if (Str[j] == '1') S.num |= (1 << (i * 5 + j));if (Str[j] == '*') S.pos = i * 5 + j;}}Ans = IDAStar(S);printf("%d\n", Ans);} return 0; }
转载于:https://www.cnblogs.com/JoeFan/p/4160896.html
[BZOJ 1085] [SCOI2005] 骑士精神 [ IDA* 搜索 ]相关推荐
- bzoj 1085: [SCOI2005]骑士精神(IDA*)
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2296 Solved: 1328 [Submit][St ...
- BZOJ 1085 [SCOI2005]骑士精神 【A*启发式搜索】
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2838 Solved: 1663 [Submit][St ...
- 1085: [SCOI2005]骑士精神
Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑 士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2 ...
- P2324 [SCOI2005]骑士精神(IDA*)
思路:不是动骑士,而是动空格.只能动15次,证明搜索树的高的确定的,考虑IDA解决 IDA能很好地解决一些搜索中有上界的情况 大概就是搞一个估值函数,然后当前情况+估价函数>限制的情况直接剪掉这 ...
- luoguP2324 [SCOI2005]骑士精神 IDA*
题面 这个题比较简单 直接枚举搜索深度 估价函数为当前棋盘与目标棋盘不同的棋的个数 然后直接迭代加深搜索就可以了 当然还不能走回头路 Codes #include<bits/stdc++.h&g ...
- bzoj1085骑士精神(搜索)
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1893 Solved: 1051 Description ...
- bzoj1085: [SCOI2005]骑士精神(a*)
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2555 Solved: 1472 [Submit][St ...
- 洛谷 P2324 [SCOI2005]骑士精神 解题报告
P2324 [SCOI2005]骑士精神 题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,* ...
- 【BZOJ1085】【SCOI2005】骑士精神 [A*搜索]
骑士精神 Time Limit: 10 Sec Memory Limit: 162 MB [Submit][Status][Discuss] Description 在一个5×5的棋盘上有12个白色 ...
最新文章
- 《C#精彩实例教程》小组阅读09 -- C#数组与集合
- java项目使用过滤器实例_Java web开发--过滤器篇(详细介绍)
- SpringMvc之整合DWR3.0.0推送消息
- php解压功能的函数
- C和指针之memmove函数 memcpy函数 strcspn函数 strspn函数 strrstr函数实现
- python将字典写入csv_Python如何把字典写入到CSV文件的方法示例
- 蓝桥杯 BASIC-20 基础练习 数的读法 问题
- 模板之家php mysql_PHP+APACHE+MYSQL安装方法
- 【iOS】彩虹渐变色 的 Swift 实现
- 百面机器学习—5.SVM要点总结
- setTimeout/setInterval伪异步
- python报表自动化系列 - 获得指定目录下所有文件名
- linux下查看so文件内容,linux查看so文件的一些信息命令
- Spring Boot-1 (IntelliJ IDEA + gradle)
- 深入探索 Android 网络优化(二、网络优化基础篇)上
- 组建自己的局域网(可以将PC机实现为服务器)
- sublime:下载免费历史版本
- java系统接口开发_模拟用户管理系统java接口开发与测试实战
- 笔戈科技到底是不是魅族的?
- 2012年移动SEO启示
热门文章
- POSIX风格正则表达式
- Pro*c使用滚动游标进行更新或删除游标行
- 轻松访问 Android 系统源码与下载
- JAVA进阶day07JNI(java调用c)B部分
- React开发(210):react中try...catch..
- [css] 说说你对CSS样式覆盖规则的理解
- [css] 如何让IE6支持min-width和max-width?
- 前端学习(2706):重读vue电商网站26之JSON格式的配置文件
- 前端学习(2226):react之状态
- 前端学习(1166):扩展运算符02