智商是硬伤系列之二...
马踏棋盘
题目描述就不讲了,下面先写写思路:
定义
s1 当前所在位置存储的下一步的所有可走路线
s[65] s[step] 存储的下一步的所有可走路线
函数
Number下一步可走的数目
Exit 下一步可走的位置,并且压入s[step]
思路:
1.GetOrdnance 输入初始坐标
2.InitStack 栈的初始化操作
3.Next step关键步骤
----1.当前栈的初始化操
----2.将当前所在位置压入临时栈s1
----3.当前step的下一步所有可走路线s[step]
----4.先pop一个下一步可走路线
--------1.如果没有下一步可以走了,回溯操作
--------2.下一步是死路,换种下一步的走法
--------3.下一步有走的位置,但是s[step]为空了,直接走下一步
4.其他情况??
4.PrintChessBoard打印棋盘操作
Horse.cpp
#include "SqStack.h"
#define N 8
//马的走位
int HTry1[] = {-2, -1, 1, 2, 2, 1, -1, -2}; //x方向走位
int HTry2[] = {1, 2, 2, 1, -1, -2, -2, -1}; //y方向走位
//标识
int board[N][N] = {0}; //N * N 个棋盘
int step = 1; //已经走的步数
SqStack s[65]; //第step步的下一步的所有可能位置
SqStack s1; //临时栈
//函数定义
void GetOrdnance(Point &p); //获得坐标
void Exit(Point p); //计算下一步
int Number(Point p); //找出当前位置下一步的各种可能位置,计算可能之和
void Next(Point p); //找出各个位置并将其步数记录
bool Legal(Point p); //判断是否可行
void PrintChessBoard(int board[N][N]); //打印棋盘
int main()
{
Point p;
GetOrdnance(p);
InitStack(s1);
Next(p);
PrintChessBoard(board);
return 0;
}
void GetOrdnance(Point &p)
{
printf("输入 x ( 0 - %d ), y ( 0 - %d )\n", N - 1, N - 1);
scanf("%d%d", &p.x, &p.y);
//判断输入是否合法
while (! ((p.x >= 0) && (p.x < N - 1) && (p.y >= 0) && (p.y < N - 1)) )
{
printf("输入不合法,请重新输入\n");
printf("输入 x ( 0 - %d ), y ( 0 - %d )\n", N - 1, N -1);
scanf("%d%d", &p.x, &p.y);
}
}
void PrintChessBoard(int board[N][N])
{
int i = 0;
int j = 0;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
printf("%5d", board[i][j]);
}
printf("\n");
}
}
int Number(Point p)
{
Point p1;
int j = 0;
for (int i = 0; i < 8; i++)
{
p1.x = p.x + HTry1[i];
p1.y = p.y + HTry2[i];
if (Legal(p1))
{
j++;
}
}
return j;
}
void Next(Point p)
{
Point p1, p2; //p2存储下一步要走的位置 p1存储当前位置
InitStack(s[step]);
board[p.x][p.y] = step;
Push(s1, p); //将当前所在位置压入临时栈s1
if (step < N * N)
{
Exit(p);
Pop(s[step], p2); //p2是从s[step]里pop出来的
if ((s[step].base == s[step].top && Number(p2) == 0) && step != N * N - 1) //s[step]为空栈 下一步不能走了 步数没有到64
{ //这个时候我们需要回溯操作
Pop(s1, p1); //把当前位置从临时栈s1里pop出来
board[p1.x][p1.y] = 0; //清零操作
--step; //步数减1
while (s[step].base == s[step].top) //清除s[step]栈为空栈
{
Pop(s1, p1); //从s1中弹栈放到p1中
board[p1.x][p1.y] = 0;
step--; //一直回溯到能走为止
}
Pop(s[step], p2); //换一种下一步的走法
step++;
Next(p2);
}
else if (Number(p2) == 0 && s[step].base != s[step].top)//下一步没有走的位置 栈不为空
{
Pop(s[step], p2); //换一种下一步的走法
step++;
Next(p2);
}
else if (Number(p2) != 0 && s[step].base == s[step].top)//下一步有走的位置 但是栈s[step]为空
{ //直接走下一步
step++;
Next(p2);
}
else
{
step++;
Next(p2);
}
}
}
void Exit(Point p)
{
Point temp;
Point p1;
int j = 0;
Point ap[8] = {0};
for (int i = 0; i < 8; i++)
{
p1.x = p.x + HTry1[i];
p1.y = p.y + HTry2[i];
if (Legal(p1))
{
ap[j] = p1;
j++;
}
}//将下一步的可能位置存储在ap[]中
for (int count = 0; count < Number(p) - 1; count++)
{
for (int k = 0; k < Number(p) - 1; k++)
{
if (Number(ap[k]) < Number(ap[k+1])) //从大到小排列
{
temp = ap[k+1];
ap[k+1] = ap[k];
ap[k] = temp;
}
}
}
for (int t = 0; t < Number(p); t++) { Push(s[step], ap[t]); //从大到小压入s[step]栈中,pop的时候就是从小到大 } } bool Legal(Point p) { if ((p.x >= 0) && (p.x < N) && (p.y >= 0) && (p.y < N) && (board[p.x][p.y] == 0))
return true;
else
return false;
}
SqStack.h
#include <stdio.h>
#include <malloc.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMEMNT 10 //存储空间分配增量
typedef struct _Point{
int x;
int y;
}Point;
typedef Point SElemType;
typedef int Status;
typedef struct _SqStack
{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
/*基本操作的函数原型说明*/
//构造一个空栈
Status InitStack(SqStack &s);
//销毁栈S,S不再存在
Status DestroyStack(SqStack &s);
//把S置为空栈
Status ClearStack(SqStack &s);
//判断栈是否为空栈
Status StackEmpty(SqStack S);
//返回S的元素个数,即栈的长度
int StackLength(SqStack s);
//返回栈顶元素
Status GetTop(SqStack s, SElemType &e);
//进栈操作
Status Push(SqStack &s, SElemType e);
//出栈操作
Status Pop (SqStack &s, SElemType &e);
SqStack.cpp
#include "SqStack.h"
Status InitStack(SqStack &s)
{
//构造一个空栈 S
s.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
//存储分配失败
if (!s.base)
return OVERFLOW;
s.top = s.base;
s.stacksize = STACK_INIT_SIZE;
return OK;
}
//销毁栈S,S不再存在
Status DestroyStack(SqStack &s);
//把S置为空栈
Status ClearStack(SqStack &s);
//判断栈是否为空栈
Status StackEmpty(SqStack S);
//返回S的元素个数,即栈的长度
int StackLength(SqStack s);
Status GetTop(SqStack s, SElemType &e)
{
//若栈不为空,用e返回s的栈顶元素,并返回OK;否则返回ERROR
if (s.top == s.base)
return ERROR;
e = *(s.top - 1);
return OK;
}
Status Push(SqStack &s, SElemType e)
{
//插入元素e为新的栈顶元素
if (s.top - s.base >= s.stacksize)
{
//栈满,追加空间
s.base = (SElemType*) realloc(s.base, (s.stacksize + STACK_INIT_SIZE) * sizeof(SElemType));
if (!s.base)
return OVERFLOW;
s.top = s.base + s.stacksize;
s.stacksize += STACKINCREMEMNT;
}
*s.top++ = e;
return OK;
}
Status Pop (SqStack &s, SElemType &e)
{
if (s.top == s.base)
return ERROR;
e = * --s.top;
return OK;
}