马踏棋盘

来源:互联网 发布:jsp和js交互 编辑:程序博客网 时间:2024/04/30 23:08

 //*****stack.h
#ifndef _STACK_H
#define _STACK_H
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int Status;
template<class QElemType>
class stack
{
public:
 void InitStack();
 void DestroyStack();
 void ClearStack();
 Status StackEmpty();
 Status StackLength();
 void GetTop(QElemType & e);
 void Push(QElemType e);
 void Pop(QElemType & e);
private:
 struct SqStack{
  QElemType *base;
  QElemType *top;
  int stacksize;
 }S;
};
//******stack.cpp------
template<class QElemType>
void stack<QElemType>::InitStack()
{
 S.base = (QElemType *)malloc(STACK_INIT_SIZE * sizeof(QElemType));
 if(!S.base) exit(0);
 S.top = S.base;
 S.stacksize = STACK_INIT_SIZE;
}
template <class QElemType>
void stack<QElemType>::DestroyStack()
{
 free(S.base);
}
template <class QElemType>
void stack<QElemType>::ClearStack()
{
 S.top = S.base;
}
template <class QElemType>
Status stack<QElemType>::StackEmpty()
{
 if(S.top == S.base) return 1;
 else return 0;
}
template <class QElemType>
Status stack<QElemType>::StackLength()
{
 return (S.top - S.base);
}
template <class QElemType>
void stack<QElemType>::GetTop(QElemType & e)
{
 if(S.top != S.base)
  e = *(S.top - 1);
 else e = NULL;
}
template <class QElemType>
void stack<QElemType>::Push(QElemType e)
{
 if(S.top - S.base >= S.stacksize)
 {
  S.base = (QElemType *)realloc(S.base,(S.stacksize + STACKINCREMENT) * sizeof(QElemType));
  if(!S.base) exit(0);
  S.top = S.base + S.stacksize;
  S.stacksize += STACKINCREMENT;
 }
 *S.top++ = e;
}
template <class QElemType>
void stack<QElemType>::Pop(QElemType & e)
{
 if(S.top == S.base) e = NULL;
 else
  e = * --S.top;
}
//**********stack.cpp
#endif     //stack.h ****

 

 

 

 

#include <iostream>
#include <iomanip>
#include "stack.h"
using namespace std;

#define Max 16
bool tag[Max][Max];
int passed[Max][Max];                                   //记录已经走过的点
int pos[8][2] = {
 {-1,-2},
 {-2,-1},
 {-2,1},
 {-1,2},
 {1,2},
 {2,1},
 {2,-1},
 {1,-2}
};
int deg(int x,int y);                                    //求点(X,Y)下步能到的位置总数,为确定下个跳点准备
void printpath(stack<int> &SX,stack<int> &SY);
void Solution(int x,int y,stack<int> &SX,stack<int> &SY);
int main()
{
 memset(tag,0,Max*Max*sizeof(bool));        //初始化
 memset(passed,0,Max*Max*sizeof(int));

 int x,y;
 cout << "输入起始点,如3 4:" << endl;
    cin >> x >> y;
 tag[x-1][y-1] = 1;

    stack<int> SX,SY;                            //SX,SY分别存储横纵坐标,两者是同步的
 SX.InitStack();
 SY.InitStack();
 Solution(x-1,y-1,SX,SY);
 printpath(SX,SY);
 return 0;
}

int deg(int x,int y)
{
 int x1,y1;
 int count = 8;
 for(int i = 0;i < 8;i++)
 {
  x1 = x+pos[i][0];
  y1 = y+pos[i][1];
  if(x1 < 0 || x1 > Max-1
   || y1 < 0 || y1 > Max-1
    || tag[x1][y1])
    count--;
 }
 return count;
}

void Solution(int x,int y,stack<int> &SX,stack<int> &SY)
{
    SX.Push(x);SY.Push(y);
 int i,j;
 while(!SX.StackEmpty() && SX.StackLength() != Max*Max)
 {

  SX.GetTop(i);SY.GetTop(j);
        int x,y,min = INT_MAX;
  int m,n,l = -1;
  for(int k = 0;k < 8;k++)                                 //确定下个跳点
  {
   x = i+pos[k][0];
   y = j+pos[k][1];
   if(x >= 0 && x < Max
    && y >= 0 && y < Max
    && !tag[x][y] && /*deg(x,y) > 0                         //注意此处的deg(x,y) > 0,如果加上,最后一步不能成功
    &&*/ deg(x,y) < min && ((passed[i][j]&1<<k) == 0))
   {
    min = deg(x,y);
    m = x,n = y;
    l = k;
   }
  }
  if(l != -1)
  {
   passed[i][j] += 1<<l;
   SX.Push(m);
   SY.Push(n);
   tag[m][n] = 1;
  }
  else
  {
   SX.Pop(i);
   SY.Pop(j);
   tag[i][j] = 0;
   passed[i][j] = 0;
  }

 }
  
}

void printpath(stack<int> &SX,stack<int> &SY)
{
 if(SX.StackEmpty())
 {
  cout << "No Answer!" << endl;
  return;
 }
 int a[Max][Max];
 int count = Max*Max;
 int i,j;
 while(!SX.StackEmpty())
 {
  SX.Pop(i);
  SY.Pop(j);
  a[i][j] = count--;
 }
 for(i = 0;i < Max;i++)
 {
  for(j = 0;j < Max;j++)
  {
   cout.width(4);
   cout << a[i][j];
  }
  cout << endl;
 }
 SX.DestroyStack();
 SY.DestroyStack();
}