独立钻石跳棋问题的C++实现
2006-05-09 23:52
411 查看
/**********************************说明***********************************/
/*
问题描述:
独立钻石跳棋问题。在下图中,33个方格顶点摆放着32枚棋子,仅中央的顶点空着未摆放棋子。
下棋的规则是任一棋子可以沿水平或成垂直方向跳过与其相邻的棋子,进入空着的顶点并吃掉被跳过的棋子。
试设计一个算法找出一种下棋方法,使得最终棋盘上只剩下一个棋子在棋盘中央。
0------------------------->x
| 01 2 3456
| * * * 0 3
| * * * 1 |
| * * * * * * * 2 |
| * * * . * * * 3 方向确定规定为: 2<-----*----->0
| * * * * * * * 4 |
| * * * 5 |
| * * * 6 1
y
*/
/*************************************************************************/
#include <iostream>
#include <fstream>
using namespace std;
struct step //记录移动棋子的信息
{
int sx, sy; // 记录移动棋子前棋子的位置
int tx, ty; // 记录移动棋子后棋子的位置
int dir; // dir值代表移动棋子的方向
};
struct step mystack[100], last_step;
char diamond[7][7];
int Left_diamond = 32;
int x, y, nx, ny, ndir, top; // ndir值代表方向, 0代表向右, 1代表向下, 2代表向左, 3代表向上
int flag=1; // 是否成功找到解的标志
/*****************************初始化棋盘*****************************/
void Init_diamond()
{
for(int i=0; i<7; i++)
{
for(int j=0; j<7; j++)
{
if((i<2 || i>4) && (j<2 || j>4));
else
{
diamond[i][j] = '*';
}
}
}
diamond[3][3] = '.';
}
/*********************************************************************/
/*******************************移动棋子******************************/
int Move_diamond(int y, int x, int dir)
{
if(diamond[y][x] != '*')
{
return 0;
}
struct step temp;
switch(dir)
{
case 0:
if(x+2>6 || diamond[y][x+1]!='*' || diamond[y][x+2]!='.')
{
return 0;
}
diamond[y][x] = diamond[y][x+1] = '.';
diamond[y][x+2] = '*';
temp.sx = x;
temp.sy = y;
temp.tx = x+2;
temp.ty = y;
temp.dir = dir;
mystack[top++] = temp;
return 1;
break;
case 1:
if(y+2>6 || diamond[y+1][x]!='*' || diamond[y+2][x]!='.')
{
return 0;
}
diamond[y][x] = diamond[y+1][x] = '.';
diamond[y+2][x] = '*';
temp.sx = x;
temp.sy = y;
temp.tx = x;
temp.ty = y+2;
temp.dir = dir;
mystack[top++] = temp;
return 1;
break;
case 2:
if(x-2<0 || diamond[y][x-1]!='*' || diamond[y][x-2]!='.')
{
return 0;
}
diamond[y][x] = diamond[y][x-1] = '.';
diamond[y][x-2] = '*';
temp.sx = x;
temp.sy = y;
temp.tx = x-2;
temp.ty = y;
temp.dir = dir;
mystack[top++] = temp;
return 1;
break;
case 3:
if(y-2<0 || diamond[y-1][x]!='*' || diamond[y-2][x]!='.')
{
return 0;
}
diamond[y][x] = diamond[y-1][x] = '.';
diamond[y-2][x] = '*';
temp.sx = x;
temp.sy = y;
temp.tx = x;
temp.ty = y-2;
temp.dir = dir;
mystack[top++] = temp;
return 1;
break;
default:
break;
}
return 0;
}
/*********************************************************************/
/*******************************主函数********************************/
void main()
{
// 输出一个解到文本文件answer.txt
ofstream answer("answer.txt");
Init_diamond();
top = nx = ny = ndir = 0;
// 回溯遍历,直到找到一个解
while(1)
{
if(Left_diamond == 1 && diamond[3][3] == '*')
{
break;
}
for(y=ny; y<7; y++,nx=0)
{
for(x=nx; x<7; x++,ndir=0)
{
for(int dir=ndir; dir<4; dir++)
{
if(Move_diamond(y, x, dir))
{
Left_diamond--;
nx = ny = ndir = 0;
goto nextstep;
}
}
}
}
nextstep:
if(y == 7)
{
top--;
// 回到上一步, 并改变方向
if(top >= 0)
{
last_step = mystack[top];
diamond[(last_step.sy + last_step.ty)/2][(last_step.sx + last_step.tx)/2] = '*';
diamond[last_step.sy][last_step.sx] = '*';
diamond[last_step.ty][last_step.tx] = '.';
nx = last_step.sx;
ny = last_step.sy;
ndir = last_step.dir + 1;
Left_diamond++;
}
else
{
answer<<"Can't find any answer, I am sorry."<<endl;
cout<<"Can't find any answer, I am sorry."<<endl;
flag=0;
break;
}
}
}
Init_diamond();
answer<<"The initialization diamond states:"<<endl;
for(int i=0; i<7; i++)
{
for(int j=0; j<7; j++)
{
answer<<diamond[i][j]<<' ';
}
answer<<endl;
}
answer<<endl<<endl;
// 输出解
for(int n=0; n<top; n++)
{
answer<<"step "<<n+1<<": Move diamond ("<<mystack
.sy+1<<","
<<mystack
.sx+1<<") ---> ("<<mystack
.ty+1<<","<<mystack
.tx+1<<")"<<endl;
diamond[mystack
.sy][mystack
.sx] = '.';
diamond[(mystack
.sy+mystack
.ty)/2][(mystack
.sx+mystack
.tx)/2] = '.';
diamond[mystack
.ty][mystack
.tx] = '*';
answer<<"Left diamonds : "<<top-n<<endl;
for(int k=0; k<7; k++)
{
for(int j=0; j<7; j++)
{
answer<<diamond[k][j]<<' ';
}
answer<<endl;
}
answer<<endl<<endl;
}
if(flag)
{
86fb
cout<<"The answer has been exported to file /"answer.txt/" in the same directory.Welcome to see!"<<endl;
}
}
/*********************************************************************/
/*
问题描述:
独立钻石跳棋问题。在下图中,33个方格顶点摆放着32枚棋子,仅中央的顶点空着未摆放棋子。
下棋的规则是任一棋子可以沿水平或成垂直方向跳过与其相邻的棋子,进入空着的顶点并吃掉被跳过的棋子。
试设计一个算法找出一种下棋方法,使得最终棋盘上只剩下一个棋子在棋盘中央。
0------------------------->x
| 01 2 3456
| * * * 0 3
| * * * 1 |
| * * * * * * * 2 |
| * * * . * * * 3 方向确定规定为: 2<-----*----->0
| * * * * * * * 4 |
| * * * 5 |
| * * * 6 1
y
*/
/*************************************************************************/
#include <iostream>
#include <fstream>
using namespace std;
struct step //记录移动棋子的信息
{
int sx, sy; // 记录移动棋子前棋子的位置
int tx, ty; // 记录移动棋子后棋子的位置
int dir; // dir值代表移动棋子的方向
};
struct step mystack[100], last_step;
char diamond[7][7];
int Left_diamond = 32;
int x, y, nx, ny, ndir, top; // ndir值代表方向, 0代表向右, 1代表向下, 2代表向左, 3代表向上
int flag=1; // 是否成功找到解的标志
/*****************************初始化棋盘*****************************/
void Init_diamond()
{
for(int i=0; i<7; i++)
{
for(int j=0; j<7; j++)
{
if((i<2 || i>4) && (j<2 || j>4));
else
{
diamond[i][j] = '*';
}
}
}
diamond[3][3] = '.';
}
/*********************************************************************/
/*******************************移动棋子******************************/
int Move_diamond(int y, int x, int dir)
{
if(diamond[y][x] != '*')
{
return 0;
}
struct step temp;
switch(dir)
{
case 0:
if(x+2>6 || diamond[y][x+1]!='*' || diamond[y][x+2]!='.')
{
return 0;
}
diamond[y][x] = diamond[y][x+1] = '.';
diamond[y][x+2] = '*';
temp.sx = x;
temp.sy = y;
temp.tx = x+2;
temp.ty = y;
temp.dir = dir;
mystack[top++] = temp;
return 1;
break;
case 1:
if(y+2>6 || diamond[y+1][x]!='*' || diamond[y+2][x]!='.')
{
return 0;
}
diamond[y][x] = diamond[y+1][x] = '.';
diamond[y+2][x] = '*';
temp.sx = x;
temp.sy = y;
temp.tx = x;
temp.ty = y+2;
temp.dir = dir;
mystack[top++] = temp;
return 1;
break;
case 2:
if(x-2<0 || diamond[y][x-1]!='*' || diamond[y][x-2]!='.')
{
return 0;
}
diamond[y][x] = diamond[y][x-1] = '.';
diamond[y][x-2] = '*';
temp.sx = x;
temp.sy = y;
temp.tx = x-2;
temp.ty = y;
temp.dir = dir;
mystack[top++] = temp;
return 1;
break;
case 3:
if(y-2<0 || diamond[y-1][x]!='*' || diamond[y-2][x]!='.')
{
return 0;
}
diamond[y][x] = diamond[y-1][x] = '.';
diamond[y-2][x] = '*';
temp.sx = x;
temp.sy = y;
temp.tx = x;
temp.ty = y-2;
temp.dir = dir;
mystack[top++] = temp;
return 1;
break;
default:
break;
}
return 0;
}
/*********************************************************************/
/*******************************主函数********************************/
void main()
{
// 输出一个解到文本文件answer.txt
ofstream answer("answer.txt");
Init_diamond();
top = nx = ny = ndir = 0;
// 回溯遍历,直到找到一个解
while(1)
{
if(Left_diamond == 1 && diamond[3][3] == '*')
{
break;
}
for(y=ny; y<7; y++,nx=0)
{
for(x=nx; x<7; x++,ndir=0)
{
for(int dir=ndir; dir<4; dir++)
{
if(Move_diamond(y, x, dir))
{
Left_diamond--;
nx = ny = ndir = 0;
goto nextstep;
}
}
}
}
nextstep:
if(y == 7)
{
top--;
// 回到上一步, 并改变方向
if(top >= 0)
{
last_step = mystack[top];
diamond[(last_step.sy + last_step.ty)/2][(last_step.sx + last_step.tx)/2] = '*';
diamond[last_step.sy][last_step.sx] = '*';
diamond[last_step.ty][last_step.tx] = '.';
nx = last_step.sx;
ny = last_step.sy;
ndir = last_step.dir + 1;
Left_diamond++;
}
else
{
answer<<"Can't find any answer, I am sorry."<<endl;
cout<<"Can't find any answer, I am sorry."<<endl;
flag=0;
break;
}
}
}
Init_diamond();
answer<<"The initialization diamond states:"<<endl;
for(int i=0; i<7; i++)
{
for(int j=0; j<7; j++)
{
answer<<diamond[i][j]<<' ';
}
answer<<endl;
}
answer<<endl<<endl;
// 输出解
for(int n=0; n<top; n++)
{
answer<<"step "<<n+1<<": Move diamond ("<<mystack
.sy+1<<","
<<mystack
.sx+1<<") ---> ("<<mystack
.ty+1<<","<<mystack
.tx+1<<")"<<endl;
diamond[mystack
.sy][mystack
.sx] = '.';
diamond[(mystack
.sy+mystack
.ty)/2][(mystack
.sx+mystack
.tx)/2] = '.';
diamond[mystack
.ty][mystack
.tx] = '*';
answer<<"Left diamonds : "<<top-n<<endl;
for(int k=0; k<7; k++)
{
for(int j=0; j<7; j++)
{
answer<<diamond[k][j]<<' ';
}
answer<<endl;
}
answer<<endl<<endl;
}
if(flag)
{
86fb
cout<<"The answer has been exported to file /"answer.txt/" in the same directory.Welcome to see!"<<endl;
}
}
/*********************************************************************/
相关文章推荐
- 独立钻石跳棋问题
- 一个猴子选大王问题程序(c++实现)
- 一笔画问题的c++实现
- [UE4]C++实现动态加载的问题
- 图论中最短路径问题C++实现
- c++实现0-1背包问题完整源码(动态规划实现)
- 欧几里得旅行商问题 java与c++实现
- C/C++实现HTTP/HTTPS的POST存在的问题
- 打靶问题c++代码递归实现——程序员面试宝典
- C++实现——01背包问题
- 数据结构(19)栈典型问题之C++实现表达式求值
- hanoi塔问题解析(一) c++实现
- n-皇后问题 C++实现 回溯法
- VC++编译问题汇总1 单链表的表示和实现,基于c++
- C++实现 八皇后问题及其扩展N皇后问题(经典回溯算法)
- 棋盘的完美覆盖问题,c++代码实现
- 问题六十九:阴影(Shadow)——原理和C++实现
- Windows平台下C++插件系统实现的几个关键技术问题及其解决思路
- 有关C++ 实现时extern 和const的问题
- 最大子数组问题-c++代码实现及运行实例结果