AcWing 180. 排书
AStar 最坏情况\(O(log_2560 ^ 4)\)
用\(AStar\)算法做了这题,程序跑了\(408ms\)。
相比于\(IDA*\)的\(100ms\)左右要慢上不少。
且\(A*\)由于是\(bfs\),代码长度也较长。
跑的慢的原因应该有两点:
- 用了三个\(STL\),垃圾STL毁我青春
- 这题的指数暴涨,是\(560\),所以\(log\)反而比前几次叠加要大。
使用的估价函数是一样的,即:
\(h(n) = \lceil\frac{相邻位置不对的对数}{3}\rceil\)
估价函数详细的证明 & 解释见 y总的题解。
总结了一下应该在何时选择 \(A*\) 或 \(IDA*\):
- 需要最小字典序时,状态表示很大,指数增长较快时,使用\(IDA*\)
- 若状态容易表示,指数增长较慢时,使用\(A*\)(注意需要最小字典序时不能用\(A*\),因为他不是按照顺序搜索的)。
C++ 代码
#include <cstdio>
#include <iostream>
#include <unordered_set>
#include <queue>
using namespace std;
typedef unsigned long long ULL;
const int N = 15, B = 17;
int n;
struct State{
//v表示当前的状态,step表示步数,f表示当前估计值(答案)
int v[N], step, f;
//重载小于号
bool operator < (const State &x) const{
return f > x.f;
}
}Start;
//检测是否到了目标状态
bool check(State x){
for(int i = 0; i < n; i++)
if(x.v[i] != i + 1) return false;
return true;
}
//用于检测一个状态是否已经访问过了
unordered_set<ULL> s;
priority_queue<State> q;
//hash
ULL get(State x){
ULL res = 0;
for(int i = 0; i < n; i++)
res = res * B + x.v[i];
return res;
}
int f(State x){
int res = 0;
for(int i = 1; i < n; i++)
if(x.v[i] - 1 != x.v[i - 1]) res++;
return res % 3 ? res / 3 + 1 : res / 3;
}
int bfs(){
while(q.size()) q.pop();
Start.step = 0; Start.f = f(Start);
q.push(Start); s.insert(get(Start));
while(!q.empty()){
State u = q.top(); q.pop();
if(u.f >= 5) return 5;
if(check(u)) return u.step;
for(int l = 1; l < n; l++){
for(int i = 0; i + l - 1 < n; i++){
int j = i + l - 1;
for(int k = i + l; k < n; k++){
State v;
for(int f = 0; f < n; f++) v.v[f] = u.v[f];
for(int f = j + 1, t = i; f <= k; f++, t++)
v.v[t] = u.v[f];
for(int f = i, t = i + k - j; f <= j; f++, t++)
v.v[t] = u.v[f];
if(s.count(get(v)) > 0) continue;
s.insert(get(v));
v.step = u.step + 1;
v.f = v.step + f(v);
q.push(v);
}
}
}
}
return 5;
}
int main(){
int T; scanf("%d", &T);
while(T--){
s.clear();
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d", &Start.v[i]);
int res = bfs();
if(res >= 5) puts("5 or more");
else printf("%d\n", res);
}
return 0;
}
AcWing 180. 排书的更多相关文章
- AcWing 1023. 买书 完全背包
//完全背包 求方案数目 //f[i][j] 只从前i个物品中选,且总体积恰好为j的方案的集合 //f[i][j]=f[i-1][j]+f[i-1][j-v*1]+f[i-1][j-v*2]+...f ...
- AcWing 【算法提高课】笔记02——搜索
搜索进阶 22.4.14 (PS:还有 字串变换 A*两题 生日蛋糕 回转游戏 没做) 感觉暂时用不上 BFS 1. Flood Fill 在线性时间复杂度内,找到某个点所在的连通块 思路 统计连通块 ...
- python库-collections模块Counter类
Counter类主要是用来跟踪值出现的次数.它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value. demo: all_words = [] # 列表里面是汉字(可 ...
- [No00005F]读书与心智
读千卷书,行万里路,不够…还得有个对谈者相伴,才更有意思.十月七号晚上,与友人谈读书,线上直播,三百观众相伴,四小时畅谈,不亦乐乎! Part1:读书的载体 散发出最浓郁的知识芬芳和铭刻下最隽永的历史 ...
- 本周实验的PSP0过程文档
项目计划总结: 日期/任务 听课 编写程序 阅读相关书籍 日总计 周一 110 60 ...
- CodeForces 294B Shaass and Bookshelf 【规律 & 模拟】或【Dp】
这道题目的意思就是排两排书,下面这排只能竖着放,上面这排可以平着放,使得宽度最小 根据题意可以得出一个结论,放上这排书的Width 肯定会遵照从小到大的顺序放上去的 Because the total ...
- 第三周pspo过程文档
团队协作: 日期/任务 听课 编写程序 阅读相关书籍 日总计 周一 110 60 ...
- pspo过程文档
项目计划总结: 日期/任务 听课 编写程序 阅读相关书籍 日总计 周一 110 60 ...
- 《Word排版艺术》读后感,兼谈LaTeX
我有两年多的LaTeX使用经验,用它排实验报告.毕业论文和书籍(半本):Word的使用时间长一些,但真正用好也不过是近一两年的事.这两个软件我都 用得很熟,我想我可以一边谈谈读<Word排版艺术 ...
随机推荐
- 1-03 Java的基本程序设计结构
1-03 Java的基本程序设计结构 3.1 & 3.2 在一个单词中间使用大写字母的方式称为骆驼命名法.以其自身为例,应该写成CamelCase). 与C/C++一样,关键字void表示这个 ...
- 12.java设计模式之代理模式
基本介绍: 代理模式(Proxy)为一个对象提供一个替身,以控制对这个对象的访问.即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能,想在 ...
- a^b(取模运算)
a^b(sdtbu oj 1222) Description 对于任意两个正整数a,b(0 <= a, b < 10000)计算ab各位数字的和的各位数字的和的各位数字的和的各位数字的和. ...
- BUUCTF 不一样的flag writeup
感谢BUUCTF提供的学习平台 https://buuoj.cn 题目:不一样的flag 工具:x64dbg 这是一道内存的迷宫题,迷宫是402000处的字符串 根据经验,这应该(a行*b列)的字符, ...
- 阿里云的nginx的https配置问题
server { listen 443 ssl; server_name www.xxx域名.com; root html; index index.html index.html; ssl_cert ...
- 被 C# 的 ThreadStatic 标记的静态变量,都存放在哪里了?
一:背景 1. 讲故事 前几天公号里有一位朋友留言说,你windbg玩的溜,能帮我分析下被 ThreadStatic 修饰的变量到底存放在哪里吗?能不能帮我挖出来,其实这个问题问的挺深的,玩高级语言的 ...
- 面试官:小伙子,给我说一下mysql 乐观锁和悲观锁吧
悲观锁介绍 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中, 将数据处于锁定状态.悲观锁的实现,往往依靠数据库 ...
- python中的unittest库
1.unittest框架是python自动化测试的入门框架,它是python自带的一个模块 包含以下几个子模块 测试用例:TestCase 测试集:TestSuite 加载用例:TestLoader ...
- leetcode 56合并区间 java
//先排序,将左区间小的放在前面,然后如果前一个的右区间大于下一个的左区间,则可以合并,分别用两个下标指向当前的大区间和将要考察的小区间 class Solution { public int[ ...
- Java蓝桥杯——递归练习题:走台阶(偶数版)
递归练习题:走台阶(偶数版) 小明刚刚看完电影<第39级台阶>.离开电影院的时候,他数了数礼堂前的台阶数,恰好是39级! 站在台阶前,他突然又想着一个问题: 如果我每一步只能迈上1个或2个 ...