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 ...
随机推荐
- 搭建基于hyperledger fabric的联盟社区(三) --生成公私钥证书及配置文件
一.生成公私钥和证书 Fabric中有两种类型的公私钥和证书,一种是给节点之前通讯安全而准备的TLS证书,另一种是用户登录和权限控制的用户证书.这些证书本来应该是由CA来颁发,但是目前只有两个社区,所 ...
- docker怎么破?
为什么要装docker? 因为linux服务器不好用,很多操作不好进行,比如安装包没有管理员权限 docker可以访问本地显卡,比一般的virtual box 或者VMware都要好 怎么装docke ...
- Windows 键盘快捷键概述
在 Windows 中工作时,利用快捷键代替鼠标.可以利用键盘快捷键打开.关闭和导航“开始”菜单.桌面.菜单.对话框以及网页.键盘还可以让您更简单地与计算机交互. 单击一个标题或按 TAB 键可以突 ...
- 在Mac下配置php开发环境:Apache+php+MySql (卡在 给mysql 设置不了账号密码)
https://my.oschina.net/joanfen/blog/171109#OSC_h4_3 cmd 进入mysql的方法
- Tool:Visual Studio
ylbtech-Tool:Visual Studio Microsoft Visual Studio(简称VS)是美国微软公司的开发工具包系列产品.VS是一个基本完整的开发工具集,它包括了整个软件生命 ...
- 杂项-数学软件:MATLAB
ylbtech-杂项-数学软件:MATLAB MATLAB是美国MathWorks公司出品的商业数学软件,用于算法开发.数据可视化.数据分析以及数值计算的高级技术计算语言和交互式环境,主要包括MATL ...
- PyQt5对话框
QinputDialog 输入的值可以是字符串,数字,或者一个项目从一个列表 def showDialog(self): text, ok = QInputDialog.getText(self, ' ...
- 改变checkbox的背景颜色
input:checked{-webkit-appearance:none;background-color: #f4a100;}
- Julia - 循环
while 循环 当 while 后的条件成立的话,执行循环体内的语句,直到条件不成立,跳出循环 如果条件一直成立,或者循环体中的语句没有能让条件不成立的,则是死循环 julia> i = 1; ...
- linux中find工具
find 由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时间来了解一下.即使系统中含有网络文件系统( NFS),find命令在该文件系统中同样有效,只要你具有相应的权限. ...