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 ...
随机推荐
- PPP PDP 及GPRS
1.相关概念: PDP:Packet Data Protocol 分组数据协议 PLMN:Public Land Mobile Network,公共陆地移动网络 APN:Access Point Na ...
- ActiveMQ的多种部署方式--ActiveMQ学习之二
单点的ActiveMQ作为企业应用无法满足高可用和集群的需求,所以ActiveMQ提供了master-slave.broker cluster等多种部署方式,但通过分析多种部署方式之后我认为需要将两种 ...
- POJ1159解题心得
题目:http://poj.org/problem?id=1159 刚开始,从样例的特征去思考.总让我从回文数的角度去思考,想出几个方案,可都用了数据去检验,发现不行.如:ABCDDCB,BACDCA ...
- springmvc 打包遇到的问题
1.测试有错误,过不去,mvn install -DSkipTests 2.设置resources路径,在pom.xml中添加 <build> <resources> < ...
- oracle autotrace使用
通过以下方法可以把Autotrace的权限授予Everyone, 如果你需要限制Autotrace权限,可以把对public的授权改为对特定user的授权. D:\oracle\ora92>sq ...
- linux加程序是否当掉检测脚本
cd $(dirname $) source ~/.bash_profile SYSTEM_TIME=`date '+%Y-%m-%d %T'` count=`ps -ef |grep "p ...
- jquery 实现点击图片居住放大缩小
该功能是基于jquery实现的,所以 第一步则是引入jquery jquery下载地址:https://jquery.com/download/ 或者使用此时调试的版本(3版本) /*! jQuery ...
- Android六大进程间通信方式总结之一:基本知识
因为不同进程都是享有独立资源的,所以全局变量这些都是无效的,必须有其他的进程间通信方式. 一.基本知识 1:怎样使用多进程 Android正常使用的多进程的办法只有一种,就是在Service或Acti ...
- Java静态代码块
static{ //代码 } 在加载类的时候,会执行静态代码块-->非静态代码块--->构造函数 http://www.cnblogs.com/panjun-Donet/archive/2 ...
- BeginInvoke 方法真的是新开一个线程进行异步调用吗?
转自原文BeginInvoke 方法真的是新开一个线程进行异步调用吗? BeginInvoke 方法真的是新开一个线程进行异步调用吗? 参考以下代码: public delegate void tre ...