code1225 八数码Bfs
Bfs搜索
1.把棋盘直接作为状态:
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdlib>
using namespace std; const int n=;
const int Size=;
int flag;
struct Point{
int x,y;
};
struct Node{
int board[Size][Size];
Point space;
int step;
};
int end[]={, ,,,,,,,,};
int dx[]={-,,,}; int dy[]={,,,-};
bool visited[]; //KT
int fac[]={,,,,,,,,,};
int KT(int s[]){
int ans=,smallNum;
for(int i=;i<=n;i++){
smallNum=;
for(int j=i+;j<=n;j++){
if(s[i]>s[j])smallNum++;
}
ans+=smallNum*fac[n-i];
}
return ans;
}
void InvKT(int k,int s[]){
int t,j;
bool v[]; memset(v,false,sizeof(v));
for(int i=;i<=n;i++){
t=k/fac[n-i];
for(j=;j<=n;j++){
if(v[j]==false){
if(t==)break;
else t--;
}
}
s[i]=j; v[j]=true;
k%=fac[n-i];
}
} //零件
bool isWin(Node k){
for(int i=;i<=;i++){
for(int j=;j<=;j++){
if(k.board[i][j]!=end[(i-)*+j])return false;
}
}
return true;
}
bool vis(Node k){
int s[];
for(int i=;i<=;i++){
for(int j=;j<=;j++){
s[(i-)*+j]=k.board[i][j];
}
}
int num=KT(s);
if(visited[num]==true)return true;
else{ visited[num]=true; return false; }
}
bool check(Point p){
if(p.x>=&&p.y>=&&p.x<=&&p.y<=)return true;
else return false;
}
void swapBoard(Node& k,Point a,Point b){
int temp=k.board[a.x][a.y];
k.board[a.x][a.y]=k.board[b.x][b.y];
k.board[b.x][b.y]=temp;
}
void outPut(Node a){
cout<<"This is a Node:"<<endl;
for(int i=;i<=;i++){
for(int j=;j<=;j++){
cout<<a.board[i][j]<<' ';
}
cout<<endl;
}
cout<<"Space: "<<a.space.x<<' '<<a.space.y<<endl;
cout<<"Step: "<<a.step<<endl; flag++;
if(flag>)exit();
} //Bfs
int bfs(Node start){
memset(visited,false,sizeof(visited));
queue<Node> q;
q.push(start);
vis(start); while(!q.empty()){
Node k=q.front(); q.pop();
//outPut(k);
for(int i=;i<;i++){
Point newSpace=k.space; newSpace.x+=dx[i]; newSpace.y+=dy[i];
if(check(newSpace)){
Node t=k;
swapBoard(t,t.space,newSpace);
t.space=newSpace; t.step++;
if(isWin(t))return t.step;
if(!vis(t))q.push(t);
}
}
}
return -;
} //Main
int main(){
freopen("1225.in","r",stdin); char cc; Node start;
for(int i=;i<=;i++){
for(int j=;j<=;j++){
cin>>cc;
if(cc==''){
start.board[i][j]=;
start.space.x=i; start.space.y=j;
}
else start.board[i][j]=cc-'';
}
}
start.step=;
cout<<bfs(start)<<endl; fclose(stdin);
return ;
}
测试点#1.in 结果:AC 内存使用量: 488kB 时间使用量: 1ms
测试点#2.in 结果:AC 内存使用量: 1128kB 时间使用量: 3ms
测试点#3.in 结果:AC 内存使用量: 1128kB 时间使用量: 6ms
测试点#4.in 结果:AC 内存使用量: 620kB 时间使用量: 2ms
测试点#5.in 结果:AC 内存使用量: 748kB 时间使用量: 1ms
2.把棋盘的康拓作为状态(为A*做准备):
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdlib>
using namespace std; const int n=;
const int Size=;
int flag;
struct Point{
int x,y;
};
int end[]={, ,,,,,,,,};
int KTend=-;
int dx[]={-,,,}; int dy[]={,,,-};
bool visited[];
int f[],step[],h[]; //KT
int fac[]={,,,,,,,,,};
int KT(int s[]){
int ans=,smallNum;
for(int i=;i<=n;i++){
smallNum=;
for(int j=i+;j<=n;j++){
if(s[i]>s[j])smallNum++;
}
ans+=smallNum*fac[n-i];
}
return ans;
}
int KT(int s[Size][Size]){
int a[];
for(int i=;i<=;i++){
for(int j=;j<=;j++){
a[(i-)*+j]=s[i][j];
}
}
return KT(a);
}
void InvKT(int k,int s[]){
int t,j;
bool v[]; memset(v,false,sizeof(v));
for(int i=;i<=n;i++){
t=k/fac[n-i];
for(j=;j<=n;j++){
if(v[j]==false){
if(t==)break;
else t--;
}
}
s[i]=j; v[j]=true;
k%=fac[n-i];
}
}
void InvKT(int k,int s[Size][Size]){
int a[];
InvKT(k,a);
for(int i=;i<=;i++){
for(int j=;j<=;j++){
s[i][j]=a[(i-)*+j];
}
}
} //零件
bool isWin(int kt){
if(KTend==-)KTend=KT(end);
return KTend==kt;
}
bool vis(int kt){
if(visited[kt]==true)return true;
else{ visited[kt]=true; return false; }
}
bool check(Point p){
if(p.x>=&&p.y>=&&p.x<=&&p.y<=)return true;
else return false;
}
void swapBoard(int board[Size][Size],Point a,Point b){
int temp=board[a.x][a.y];
board[a.x][a.y]=board[b.x][b.y];
board[b.x][b.y]=temp;
}
Point getSpacePoint(int board[Size][Size]){
Point p;
for(int i=;i<=;i++){
for(int j=;j<=;j++){
if(board[i][j]==){
p.x=i; p.y=j;
break;
}
}
}
return p;
}
void copy(int a[Size][Size],int b[Size][Size]){
for(int i=;i<=;i++){
for(int j=;j<=;j++){
b[i][j]=a[i][j];
}
}
} //Bfs
int bfs(int start){
memset(visited,false,sizeof(visited));
queue<int> q;
q.push(start);
vis(start);
step[start]=; while(!q.empty()){
int kt=q.front(); q.pop();
int s[Size][Size]; InvKT(kt,s);
Point space=getSpacePoint(s);
for(int i=;i<;i++){
Point space2=space; space2.x+=dx[i]; space2.y+=dy[i];
if(check(space2)){
int s2[Size][Size]; copy(s,s2);
swapBoard(s2,space,space2);
int kt2=KT(s2); step[kt2]=step[kt]+;
if(isWin(kt2))return step[kt2];
if(!vis(kt2))q.push(kt2);
}
}
}
return -;
} //Main
int main(){
freopen("1225.in","r",stdin); char cc; int start[];
for(int i=;i<=n;i++){
cin>>cc;
if(cc=='')start[i]=;
else start[i]=cc-'';
}
int KTstart=KT(start);
cout<<bfs(KTstart)<<endl; fclose(stdin);
return ;
}
测试点#1.in 结果:AC 内存使用量: 620kB 时间使用量: 1ms
测试点#2.in 结果:AC 内存使用量: 2024kB 时间使用量: 8ms
测试点#3.in 结果:AC 内存使用量: 2028kB 时间使用量: 6ms
测试点#4.in 结果:AC 内存使用量: 1772kB 时间使用量: 2ms
测试点#5.in 结果:AC 内存使用量: 1772kB 时间使用量: 3ms
code1225 八数码Bfs的更多相关文章
- hdu-1043(八数码+bfs打表+康托展开)
参考文章:https://www.cnblogs.com/Inkblots/p/4846948.html 康托展开:https://blog.csdn.net/wbin233/article/deta ...
- HDU1043 八数码(BFS + 打表)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 , 康托展开 + BFS + 打表. 经典八数码问题,传说此题不做人生不完整,关于八数码的八境界 ...
- 紫书p199 八数码(BFS,hash)
八数码问题 紫书上的简单搜索 渣渣好久才弄懂 #include<cstdio> #include<cstring> using namespace std; const i ...
- POJ1077 八数码 BFS
BFS 几天的超时... A*算法不会,哪天再看去了. /* 倒搜超时, 改成顺序搜超时 然后把记录路径改成只记录当前点的操作,把上次的位置记录下AC..不完整的人生啊 */ #include < ...
- luogu_1379 八数码难题
八数码-->BFS+set #include<iostream> #include<cstdlib> #include<cstdio> #include< ...
- BFS(八数码) POJ 1077 || HDOJ 1043 Eight
题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状 ...
- UVALive 6665 Dragonâs Cruller --BFS,类八数码问题
题意大概就是八数码问题,只不过把空格的移动方式改变了:空格能够向前或向后移动一格或三格(循环的). 分析:其实跟八数码问题差不多,用康托展开记录状态,bfs即可. 代码: #include <i ...
- [cdoj1380] Xiper的奇妙历险(3) (八数码问题 bfs + 预处理)
快要NOIP 2016 了,现在已经停课集训了.计划用10天来复习以前学习过的所有内容.首先就是搜索. 八数码是一道很经典的搜索题,普通的bfs就可求出.为了优化效率,我曾经用过康托展开来优化空间,甚 ...
- 八数码问题+路径寻找问题+bfs(隐式图的判重操作)
Δ路径寻找问题可以归结为隐式图的遍历,它的任务是找到一条凑够初始状态到终止问题的最优路径, 而不是像回溯法那样找到一个符合某些要求的解. 八数码问题就是路径查找问题背景下的经典训练题目. 程序框架 p ...
随机推荐
- 如何把SQLServer数据库从高版本降级到低版本
如何把SQLServer数据库从高版本降级到低版本 编写人:CC阿爸 2015-4-7 近期在给一个客户推行ECM系统时,基本客户的硬件环境,我们为其安装的为SQL2008 64位的数据库系统.在安装 ...
- STL容器——对map排序
STL容器(三)——对map排序 对于map的排序问题,主要分为两部分:根据key排序:根据value排序.下面我们就分别说一下~ 1. 根据key进行排序 map默认按照key进行升序排序 ,和输入 ...
- Java 成员变量和局部变量
1.成员变量 在类中定义,用来描述对象将要有什么. 2.局部变量 在类的方法中定义,在方法中临时保存数据. 成员变量和局部变量的区别 作用域不同: 局部变量的作用域仅限于定义它的方法 成员变量的作用域 ...
- 汇编_指令_LEA和MOV的区别
就是目标地址传送指令: 将一个近地址指针写入到指定的寄存器.格式: LEA reg16,mem16 其中reg16必须是一个16位通用寄存器,mem16必须是一个存储器,执行这个指令后,就将mem16 ...
- lamp与lnmp的选择
lnmp和lamp业务上的不同 由于二者仅仅是区别在于web的选择,nginx更高效,占用资源更少,详情区别查看LNMP环境应用实践 lnmp和lamp安装上的不同 生产环境中,可能会遇到lamp架构 ...
- 【学习笔记】Markdown入门
Markdown入门 最近把博客园的编辑器换成了Markdown. 语法入门 Markdown确实好用,本来我想总结一下常用Markdown的语法,但有下面这篇文章在,我实在是不敢画蛇添足了. 基 ...
- Linux配置IP和防火墙
前言: 刚刚学完了怎么配置Linux IP和防火墙 前来总结. 准备: 需安装的: setup 正文: 安装基础包 yum groupinstall "Base" setup 选择 ...
- java根据pdf模版动态生成pdf
java根据pdf模版动态生成pdf package com.utils; import java.io.ByteArrayOutputStream; import java.io.File; imp ...
- 24_java之转换流和缓冲流
01转换流概述 * A: 转换流概述 * a: 转换流概述 * OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字节 * 将字符串按照指 ...
- Redis实战——安装
借鉴来源:https://www.cnblogs.com/codersay/p/4301677.html redis官网地址:http://www.redis.io/ 最新版本: redis-4.0. ...