栈--马踏棋盘

智商是硬伤系列之二...
马踏棋盘
题目描述就不讲了,下面先写写思路:


定义
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;
}


马踏棋盘 链表 按照老师的要求的。大家来下载吧· 但是计算算法比较冗余,计算不较慢。 #include #include "conio.h" using namespace std; #define edgetype int #define vextype int #define MAX 8 typedef struct node { int vextex;//序号 struct node *next; }edgenode; typedef struct { int vextex; int x,y; edgenode *link; }vexnode; const int px[8]={1,2,2,1,-1,-2,-2,-1}; const int py[8]={2,1,-1,-2,-2,-1,1,2}; const int L=8,H=8; vexnode ga[L*H]; //图 int visited[L*H]={0}; typedef struct /*顺序的结构体类型定义*/ { int stack[L*H]; int top; }seqstack; seqstack s; void setnull(seqstack *s) /*置空-由于c语言的数组下标是从0开始的,所以置 空操作时将顶指针放在下标为0之前,即-1处。*/ {s->top=-1;} int empty(seqstack *s) /*判断当前是否为空*/ { if(s->toptop>L*H-1) { printf("stack overflow!\n"); /*发生上溢*/ return 0; } else { s->stack[++s->top] = x; /*顶指针上移,数据元素入*/ return 1; } } int pop(seqstack *s) /*弹出当前s的顶元素*/ { if(s->toptop--; return(s->stack[s->top+1]); }/*由于return语句的特点,必须先使top减1,然后再执行return语句。而此时顶元素的表示应该为s->top+1.*/ } void init() { int n; for (int i=0;i<H;i++) { for (int j=0;j<L;j++) { n=L*i+j; ga[n].vextex=n; ga[n].x=j; ga[n].y=i; ga[n].link=NULL; } } printf("\n"); for (i=0;i<L*H;i++) //列出邻接链表 { edgenode *p; for (int k=0;k<MAX;k++) { int tx=ga[i].x+px[k]; int ty=ga[i].y+py[k]; if(tx<0||ty=L||ty>=H) continue; //出界了 else //采用前插法 { p=(edgenode*)malloc(sizeof(edgenode)); p->vextex=ty*L+tx; p->next=ga[i].link; ga[i].link=p; // printf("%d ",ga[i].link->vextex); } } } for (i=0;i<L*H;i++) { printf("%d ",ga[i].vextex); if (!((i+1)%L)) { printf("\n"); } } } void show() //打印邻接表 { int i; printf("\n"); for (i=0;i",ga[i].vextex); edgenode *p; p=(edgenode*)malloc(sizeof
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值