bzoj 1085: [SCOI2005]骑士精神
Description
在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士,且有一个空位。在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步数完成任务。
解题报告
这题有两种方法,这里都列举
首先是IDA,但是本人太菜,估价没写对,参考了其他人的,即与目标不同位置的棋的个数.
然后迭代搜索,如果估价值超过了迭代的值就返回即可*
另一种是作死的双向bfs+map,闲着就手写了挂链,对起点正向做一遍bfs保存状态的步数,做7层,再从终点反向做8层合并答案即可
双向bfs
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const int N=6;
struct node{
int a[N][N],x,y,dep,l;
node(){}
node(int b[N][N],int _x,int _y,int _dep,int _l){
for(int i=0;i<=5;i++)for(int j=0;j<=5;j++)a[i][j]=b[i][j];
x=_x;y=_y;dep=_dep;l=_l;
}
};
queue<node>q;
char s[7];int sa[N][N],mx[8]={1,-1,1,-1,2,-2,2,-2},my[8]={2,-2,-2,2,1,-1,-1,1};
int ta[N][N];
int f[N][N]={{0,0,0,0,0,0},{0,1,1,1,1,1},
{0,0,1,1,1,1},{0,0,0,2,1,1},
{0,0,0,0,0,1},{0,0,0,0,0,0}};
const int mod=1000005;
int head[mod],nxt[mod<<2],de[mod<<2],num=0;ll to[mod<<2];
void add(int dep){
ll sum=0;
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
sum=sum*3+ta[i][j];
int k=sum%mod;
nxt[++num]=head[k];to[num]=sum;de[num]=dep;head[k]=num;
}
int query(){
ll sum=0;
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
sum=sum*3+ta[i][j];
for(int i=head[sum%mod];i;i=nxt[i])
if(to[i]==sum)return de[i];
return -1;
}
int ans=16;
void bfs(bool op){
int x,y,tx,ty,ntt;node now;
while(!q.empty()){
now=q.front();q.pop();
x=now.x;y=now.y;
if(!op && now.dep>=7)return ;
if(op && now.dep>=8)return ;
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
ta[i][j]=now.a[i][j];
for(int i=0;i<8;i++){
if(i==now.l)continue;
tx=mx[i]+x;ty=my[i]+y;
if(tx>5 || tx<1 || ty>5 || ty<1)continue;
swap(ta[x][y],ta[tx][ty]);
ntt=query();
if(!op && ntt!=-1){
swap(ta[x][y],ta[tx][ty]);
continue;
}
if(!op)add(now.dep+1);
if(op && ntt!=-1)ans=Min(ntt+now.dep+1,ans);
q.push(node(ta,tx,ty,now.dep+1,i^1));
swap(ta[x][y],ta[tx][ty]);
}
}
}
void Clear(){
while(!q.empty())q.pop();
memset(head,0,sizeof(head));
num=0;ans=16;
}
void work()
{
Clear();
int x,y;
for(int i=1;i<=5;i++){
scanf("%s",s+1);
for(int j=1;j<=5;j++){
if(s[j]!='*')ta[i][j]=sa[i][j]=s[j]-'0';
else ta[i][j]=sa[i][j]=2,x=i,y=j;
}
}
add(0);
q.push(node(sa,x,y,0,-1));
bfs(0);
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
ta[i][j]=f[i][j];
int tmp=query();
if(tmp!=-1){printf("%d\n",tmp);return ;}
while(!q.empty())q.pop();
q.push(node(f,3,3,0,-1));bfs(1);
if(ans<16)cout<<ans<<endl;
else puts("-1");
}
int main()
{
int T;cin>>T;
while(T--)work();
return 0;
}
IDA*
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=6;
int f[N][N]={{0,0,0,0,0,0},{0,1,1,1,1,1},
{0,0,1,1,1,1},{0,0,0,2,1,1},
{0,0,0,0,0,1},{0,0,0,0,0,0}};
char s[9];int li,mx[8]={1,-1,1,-1,2,-2,2,-2},my[8]={2,-2,-2,2,1,-1,-1,1};
bool flag;
bool check(int a[N][N]){
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
if(a[i][j]!=f[i][j])return false;
return true;
}
bool Pienough(int a[N][N],int x){
int ret=0;
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++){
if(f[i][j]==a[i][j])continue;
ret++;if(ret+x>li)return false;
}
return true;
}
void dfs(int a[N][N],int x,int y,int dep){
if(check(a)){flag=true;return ;}
if(dep>=li)return ;
if(flag)return ;
int tx,ty;
for(int i=0;i<8;i++){
tx=x+mx[i];ty=y+my[i];
if(tx>5 || tx<1 || ty>5 || ty<1)continue;
swap(a[x][y],a[tx][ty]);
if(Pienough(a,dep))dfs(a,tx,ty,dep+1);
swap(a[x][y],a[tx][ty]);
}
}
void work()
{
int a[N][N],x,y;
for(int i=1;i<=5;i++){
scanf("%s",s+1);
for(int j=1;j<=5;j++){
if(s[j]!='*')a[i][j]=s[j]-'0';
else a[i][j]=2,x=i,y=j;
}
}
flag=false;
for(li=0;li<=15;li++){
dfs(a,x,y,0);
if(flag){
printf("%d\n",li);
return ;
}
}
puts("-1");
}
int main()
{
int T;cin>>T;
while(T--)work();
return 0;
}
bzoj 1085: [SCOI2005]骑士精神的更多相关文章
- Bzoj 1085: [SCOI2005]骑士精神 (dfs)
Bzoj 1085: [SCOI2005]骑士精神 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1085 dfs + 剪枝. 剪枝方法: ...
- BZOJ 1085: [SCOI2005]骑士精神( IDDFS + A* )
一开始写了个 BFS 然后就 T 了... 这道题是迭代加深搜索 + A* -------------------------------------------------------------- ...
- BZOJ 1085 [SCOI2005]骑士精神 【A*启发式搜索】
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2838 Solved: 1663 [Submit][St ...
- [BZOJ 1085] [SCOI2005] 骑士精神 [ IDA* 搜索 ]
题目链接 : BZOJ 1085 题目分析 : 本题中可能的状态会有 (2^24) * 25 种状态,需要使用优秀的搜索方式和一些优化技巧. 我使用的是 IDA* 搜索,从小到大枚举步数,每次 DFS ...
- [BZOJ 1085][SCOI2005]骑士精神(IDA*)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1085 分析: 首先第一感觉是宽搜,但是空间需要8^15*5*5,明显不够,又鉴于最大深 ...
- BZOJ.1085.[SCOI2005]骑士精神(迭代加深搜索)
题目链接 最小步数这类,适合用迭代加深搜索. 用空格走代替骑士. 搜索时记录上一步防止来回走. 不需要每次判断是否都在位置,可以计算出不在对应位置的骑士有多少个.而且每次复原一个骑士至少需要一步. 空 ...
- bzoj 1085 [SCOI2005]骑士精神——IDA*
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1085 迭代加深搜索. 估价函数是为了预计步数来剪枝,所以要优于实际步数. 没错,不是为了确定 ...
- bzoj 1085: [SCOI2005]骑士精神 IDA*
题目链接 给一个图, 目标位置是确定的, 问你能否在15步之内达到目标位置. 因为只有15步, 所以直接ida* #include<bits/stdc++.h> using namespa ...
- BZOJ 1085: [SCOI2005]骑士精神(A*算法)
第一次写A*算法(这就是A*?如果这就是A*的话,那不就只是搜索的一个优化了= =,不过h函数如果弄难一点真的有些难设计) 其实就是判断t+h(x)(t为当前步数,h(x)为达到当前状态的最小步数) ...
随机推荐
- 安装Loadrunner 11.0时,弹出缺少2.8 sp1组件--解决方案(win7)
这是因为注册表缺少FullInstallVer和Version,归根到底是madc安装的的问题 以下是解决方法: 1.运行regedit,打开注册表,进入HKEY_LOCAL_MACHINE\SOFT ...
- 老板怎么办,我们网站遭到DDoS攻击又挂了?
相信现在正在阅读此文的你,一定听说过发生在上个月的史上最大的DDoS攻击. 美国东部时间2月28日,GitHub在一瞬间遭到高达1.35Tbps的带宽攻击.这次DDoS攻击几乎可以堪称是互联网有史以来 ...
- 双击CAD对象(具有扩展数据),显示自定义对话框实现方法
转自:Cad人生 链接:http://www.cnblogs.com/cadlife/p/3463337.html 题目:双击CAD对象,显示自定义对话框实现方法 内容粘贴如下: 主要是绑定两个事件: ...
- EasyUI DataGrid 实现单行/多行编辑功能
要实现 EasyUI DataGrid 的可编辑很简单,在需要编辑的列添加 editor [编辑器]就可以了. 单行编辑 // 初始化数据列表 function initDatagrid() { $( ...
- 面向对象的PHP(5)
OOP的好处 封装 封装可以隐藏实现细节,使代码模块化,代码重用 继承 继承可以扩展已存在的代码模块(class),代码重用 多态 为了类在继承和派生的时候,保证实例的某一属性正确调用,接口重用 关键 ...
- O(logN)中logN的底数
转载:http://blog.csdn.net/jdbc/article/details/42173751 问题: 无论是计算机算法概论.还是数据结构书中, 关于算法的时间复杂度很多都用包含O(log ...
- django的models模型类的常用数据类型和选项
django框架的models模块ORM框架,能够让我们通过编写类的方式,帮助我们自动生成数据库表. 生成的数据库表名为 应用模块名称_类名 数据库表中字段名 如果我们没有在参数中指定,就是我们写的类 ...
- mysql 查询select语句汇总
数据准备: 创建表: create table students( id int unsigned primary key auto_increment not null, name varchar( ...
- Java基础语法<六> 数组 Arrays
笔记整理 来源于<Java核心技术卷 I > <Java编程思想> 允许数组长度为0 new element[0] 数组长度为0与null不同 1. 数组拷贝 允许将一 ...
- 南京邮电大学java第二次实验报告
实 验 报 告 ( 2017 / 2018学年 第2学期) 课程名称 JAVA语言程序设计 实验名称 Java集成开发环境的安装与使用. Java变量.表达式与控制结构 实验时间 2018 年 4 月 ...