题目链接 : 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* 搜索 ]相关推荐

  1. bzoj 1085: [SCOI2005]骑士精神(IDA*)

    1085: [SCOI2005]骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2296  Solved: 1328 [Submit][St ...

  2. BZOJ 1085 [SCOI2005]骑士精神 【A*启发式搜索】

    1085: [SCOI2005]骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2838  Solved: 1663 [Submit][St ...

  3. 1085: [SCOI2005]骑士精神

    Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑 士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2 ...

  4. P2324 [SCOI2005]骑士精神(IDA*)

    思路:不是动骑士,而是动空格.只能动15次,证明搜索树的高的确定的,考虑IDA解决 IDA能很好地解决一些搜索中有上界的情况 大概就是搞一个估值函数,然后当前情况+估价函数>限制的情况直接剪掉这 ...

  5. luoguP2324 [SCOI2005]骑士精神 IDA*

    题面 这个题比较简单 直接枚举搜索深度 估价函数为当前棋盘与目标棋盘不同的棋的个数 然后直接迭代加深搜索就可以了 当然还不能走回头路 Codes #include<bits/stdc++.h&g ...

  6. bzoj1085骑士精神(搜索)

    1085: [SCOI2005]骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1893  Solved: 1051 Description ...

  7. bzoj1085: [SCOI2005]骑士精神(a*)

    1085: [SCOI2005]骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2555  Solved: 1472 [Submit][St ...

  8. 洛谷 P2324 [SCOI2005]骑士精神 解题报告

    P2324 [SCOI2005]骑士精神 题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,* ...

  9. 【BZOJ1085】【SCOI2005】骑士精神 [A*搜索]

    骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MB [Submit][Status][Discuss] Description 在一个5×5的棋盘上有12个白色 ...

最新文章

  1. 《C#精彩实例教程》小组阅读09 -- C#数组与集合
  2. java项目使用过滤器实例_Java web开发--过滤器篇(详细介绍)
  3. SpringMvc之整合DWR3.0.0推送消息
  4. php解压功能的函数
  5. C和指针之memmove函数 memcpy函数 strcspn函数 strspn函数 strrstr函数实现
  6. python将字典写入csv_Python如何把字典写入到CSV文件的方法示例
  7. 蓝桥杯 BASIC-20 基础练习 数的读法 问题
  8. 模板之家php mysql_PHP+APACHE+MYSQL安装方法
  9. 【iOS】彩虹渐变色 的 Swift 实现
  10. 百面机器学习—5.SVM要点总结
  11. setTimeout/setInterval伪异步
  12. python报表自动化系列 - 获得指定目录下所有文件名
  13. linux下查看so文件内容,linux查看so文件的一些信息命令
  14. Spring Boot-1 (IntelliJ IDEA + gradle)
  15. 深入探索 Android 网络优化(二、网络优化基础篇)上
  16. 组建自己的局域网(可以将PC机实现为服务器)
  17. sublime:下载免费历史版本
  18. java系统接口开发_模拟用户管理系统java接口开发与测试实战
  19. 笔戈科技到底是不是魅族的?
  20. 2012年移动SEO启示

热门文章

  1. POSIX风格正则表达式
  2. Pro*c使用滚动游标进行更新或删除游标行
  3. 轻松访问 Android 系统源码与下载
  4. JAVA进阶day07JNI(java调用c)B部分
  5. React开发(210):react中try...catch..
  6. [css] 说说你对CSS样式覆盖规则的理解
  7. [css] 如何让IE6支持min-width和max-width?
  8. 前端学习(2706):重读vue电商网站26之JSON格式的配置文件
  9. 前端学习(2226):react之状态
  10. 前端学习(1166):扩展运算符02