简单八数码问题深搜实现
2016-11-12 10:52
267 查看
2 8 3 1 2 3
编写程序输出由 1 0 4 变为 8 0 4 的最短路径
7 6 5 7 6 5
一.简单深搜寻找最短步骤:
二.用栈实现输出路径
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
int s[10][10];
int MIN = 1000;
typedef struct Outstack//用链表实现栈
{
int x, y;
struct Outstack *next;
}OStack, *OSt;
typedef struct stack//操作栈
{
int x, y;
struct stack *next;
}Stack, *St;
OSt baseout;//输出栈
OSt topout;
St base;//操作栈
St top;
bool Check()
{
int k = 1;
for(int i = 0; i<3; i++)
{
if(s[0][i] != k++)
{
return 0;
}
}
k = 3;
for(int i = 0; i<3; i++)
{
if(s[i][2] != k++)
{
return 0;
}
}
k = 7;
for(int i = 0; i<3; i++)
{
if(s[2][i] != k--)
{
return 0;
}
}
if(s[1][0] != 8)
return 0;
return 1;
}
void Change(int x, int y, int z)//z 1234 is left up right down
{
if(z == 1)//和左交换
{
int i = s[x][y-1];
s[x][y-1] = s[x][y];
s[x][y] = i;
}
else if(z == 2)//和上交换
{
int i = s[x-1][y];
s[x-1][y] = s[x][y];
s[x][y] = i;
}
else if(z == 3)//和右交换
{
int i = s[x][y+1];
s[x][y+1] = s[x][y];
s[x][y] = i;
}
else if(z == 4)//和下交换
{
int i = s[x+1][y];
s[x+1][y] = s[x][y];
s[x][y] = i;
}
}
OSt opush(int x, int y, OSt topout)
{
OSt p;
p = (OSt)malloc(sizeof(OStack));
topout->x = x;
topout->y = y;
p->next = topout;
return p;
}
St push(int x, int y, St top)
{
St p;
p = (St)malloc(sizeof(Stack));
top->x = x;
top->y = y;
p->next = top;
return p;
}
void DFS(int x, int y, int step)
{
if(step == 0)//等于零建立操作栈
{
base = (St)malloc(sizeof(Stack));
base->next = NULL;
top = base;
}
if(Check())
{
if(step<MIN)
{
MIN = step;
topout = baseout;
St p = (St)malloc(sizeof(Stack));
p = top->next;
while(p != NULL)
{
topout = opush(p->x, p->y, topout);
p = p->next;
}
return;
}
}
if(step>10)
return;
else
{
if(y-1>-1)
{
Change(x, y, 1);
top = push(x, y-1, top);//压栈
DFS(x, y-1, step+1);
top = top->next;//回溯出栈
Change(x, y, 1);
}
if(x-1>-1)
{
Change(x, y, 2);
top = push(x-1, y, top);
DFS(x-1, y, step+1);
top = top->next;
Change(x, y, 2);
}
if(y+1<3)
{
Change(x, y
9f6d
, 3);
top = push(x, y+1, top);
DFS(x, y+1, step+1);
top = top->next;
Change(x, y, 3);
}
if(x+1<3)
{
Change(x, y, 4);
top = push(x+1, y, top);
DFS(x+1, y, step+1);
top = top->next;
Change(x, y, 4);
}
}
}
int main()
{
int x, y;
for(int i = 0; i<3; i++)
{
for(int j = 0; j<3; j++)
{
scanf("%d", &s[i][j]);
if(s[i][j] == 0)
{
x = i;
y = j;
}
}
}
baseout = (OSt)malloc(sizeof(OStack));
baseout->next = NULL;
topout = baseout;
DFS(x, y, 0);
printf("%d\n", MIN);
topout = topout->next;
while(topout!=NULL)
{
printf("%d, %d\n", topout->x, topout->y);
topout = topout->next;
}
return 0;
}
编写程序输出由 1 0 4 变为 8 0 4 的最短路径
7 6 5 7 6 5
一.简单深搜寻找最短步骤:
/* 一般用广搜寻着最短路径,因为他是按照层次来的(设置一个visit记录访问过的点), 只要找到最先到达目标的就行。 如果用深搜着最短路径,你就需要找一个最深搜到哪里,或者题目自带到哪里不可以再 搜的条件否则你就需要设置一个每条路径的最大深度,同时最后要寻找这些你找到的长 度里面那个最小,最小的为输出长度。*/ #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; int s[10][10]; int MIN = 1000; bool Check() { int k = 1; for(int i = 0; i<3; i++) { if(s[0][i] != k++) { return 0; } } k = 3; for(int i = 0; i<3; i++) { if(s[i][2] != k++) { return 0; } } k = 7; for(int i = 0; i<3; i++) { if(s[2][i] != k--) { return 0; } } if(s[1][0] != 8) return 0; return 1; } void Change(int x, int y, int z)//z 1234 is left up right down { if(z == 1)//和左交换 { int i = s[x][y-1]; s[x][y-1] = s[x][y]; s[x][y] = i; } else if(z == 2)//和上交换 { int i = s[x-1][y]; s[x-1][y] = s[x][y]; s[x][y] = i; } else if(z == 3)//和右交换 { int i = s[x][y+1]; s[x][y+1] = s[x][y]; s[x][y] = i; } else if(z == 4)//和下交换 { int i = s[x+1][y]; s[x+1][y] = s[x][y]; s[x][y] = i; } } void DFS(int x, int y, int step)//寻找最短路径要用广搜, 这是给定寻找方向来搜可以用深搜 { if(Check())//finished { if(step<MIN) MIN = step; return; } if(step>10) return ; else { if(y-1>-1)//左 { Change(x, y, 1); DFS(x, y-1, step+1); Change(x, y, 1);//回溯 思想 没有找到就退回来 } if(x-1>-1)//上 { Change(x, y, 2); DFS(x-1, y, step+1); Change(x, y, 2);//回溯 } if(y+1<3)//右 { Change(x, y, 3); DFS(x, y+1, step+1); Change(x, y, 3);//回溯 } if(x+1<3)//下 { Change(x, y, 4); DFS(x+1, y, step+1); Change(x, y, 4);//回溯 } } } int main() { int x, y; for(int i = 0; i<3; i++) { for(int j = 0; j<3; j++) { scanf("%d", &s[i][j]); if(s[i][j] == 0) { x = i; y = j; } } } DFS(x, y, 0); printf("%d\n", MIN); return 0; }
二.用栈实现输出路径
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
int s[10][10];
int MIN = 1000;
typedef struct Outstack//用链表实现栈
{
int x, y;
struct Outstack *next;
}OStack, *OSt;
typedef struct stack//操作栈
{
int x, y;
struct stack *next;
}Stack, *St;
OSt baseout;//输出栈
OSt topout;
St base;//操作栈
St top;
bool Check()
{
int k = 1;
for(int i = 0; i<3; i++)
{
if(s[0][i] != k++)
{
return 0;
}
}
k = 3;
for(int i = 0; i<3; i++)
{
if(s[i][2] != k++)
{
return 0;
}
}
k = 7;
for(int i = 0; i<3; i++)
{
if(s[2][i] != k--)
{
return 0;
}
}
if(s[1][0] != 8)
return 0;
return 1;
}
void Change(int x, int y, int z)//z 1234 is left up right down
{
if(z == 1)//和左交换
{
int i = s[x][y-1];
s[x][y-1] = s[x][y];
s[x][y] = i;
}
else if(z == 2)//和上交换
{
int i = s[x-1][y];
s[x-1][y] = s[x][y];
s[x][y] = i;
}
else if(z == 3)//和右交换
{
int i = s[x][y+1];
s[x][y+1] = s[x][y];
s[x][y] = i;
}
else if(z == 4)//和下交换
{
int i = s[x+1][y];
s[x+1][y] = s[x][y];
s[x][y] = i;
}
}
OSt opush(int x, int y, OSt topout)
{
OSt p;
p = (OSt)malloc(sizeof(OStack));
topout->x = x;
topout->y = y;
p->next = topout;
return p;
}
St push(int x, int y, St top)
{
St p;
p = (St)malloc(sizeof(Stack));
top->x = x;
top->y = y;
p->next = top;
return p;
}
void DFS(int x, int y, int step)
{
if(step == 0)//等于零建立操作栈
{
base = (St)malloc(sizeof(Stack));
base->next = NULL;
top = base;
}
if(Check())
{
if(step<MIN)
{
MIN = step;
topout = baseout;
St p = (St)malloc(sizeof(Stack));
p = top->next;
while(p != NULL)
{
topout = opush(p->x, p->y, topout);
p = p->next;
}
return;
}
}
if(step>10)
return;
else
{
if(y-1>-1)
{
Change(x, y, 1);
top = push(x, y-1, top);//压栈
DFS(x, y-1, step+1);
top = top->next;//回溯出栈
Change(x, y, 1);
}
if(x-1>-1)
{
Change(x, y, 2);
top = push(x-1, y, top);
DFS(x-1, y, step+1);
top = top->next;
Change(x, y, 2);
}
if(y+1<3)
{
Change(x, y
9f6d
, 3);
top = push(x, y+1, top);
DFS(x, y+1, step+1);
top = top->next;
Change(x, y, 3);
}
if(x+1<3)
{
Change(x, y, 4);
top = push(x+1, y, top);
DFS(x+1, y, step+1);
top = top->next;
Change(x, y, 4);
}
}
}
int main()
{
int x, y;
for(int i = 0; i<3; i++)
{
for(int j = 0; j<3; j++)
{
scanf("%d", &s[i][j]);
if(s[i][j] == 0)
{
x = i;
y = j;
}
}
}
baseout = (OSt)malloc(sizeof(OStack));
baseout->next = NULL;
topout = baseout;
DFS(x, y, 0);
printf("%d\n", MIN);
topout = topout->next;
while(topout!=NULL)
{
printf("%d, %d\n", topout->x, topout->y);
topout = topout->next;
}
return 0;
}
相关文章推荐
- A*算法的简单实现(八数码问题)
- 简单的用c++实现的八数码问题
- 用C语言实现八数码问题
- 在写rss阅读实现的blog的聚合,简单的聚合功能,发现的一点问题
- MyEclipse6.5整合flex实现与java简单通信过程中遇到的问题和注意事项
- A*算法来实现八数码的问题 C++
- 八数码问题详解(用bfs实现)
- 今天的问题:一个简单的例子,请帮我解开“接口实现Java‘隐藏实现细目’”的迷惑。
- 简单的背包问题--java递归实现
- 八数码问题--用C#实现---VS2008可以执行
- 简单的[0/1]背包问题 分别用递归与非递归实现
- java实现简单的约瑟夫环问题
- 排序问题的简单实现!
- SQLSERVER Image类型 Hibernate 映射问题 简单实现
- 简单实现系统托盘 - 回复 "闪" 的问题
- 八数码问题--A算法实现---C#实现---VS2008可以执行
- 简单实现AJAX: ASP.NET2.0 中回调的实现及常见问题的解决
- 数独问题的一种简单算法代码实现
- 使用ActionScript3基于Flex实现八数码问题启发式搜索
- 原创:Js解析xml文件并简单实现省市区级联菜单(并解决各浏览器兼容性问题).