【马踏棋盘】 数据结构

(1)   【马踏棋盘】

(2)   *问题描述:将马随机放在国际象棋的8X8棋盘Bo阿rd[0..7,0..7]的某个方格中,马按走棋规则进行移动。要求每个方格上只进入一次,走遍棋盘上全部64个方格。编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入8X8的方阵输出之。

(3)   *测试数据:由读者指定,可自行指定一个马的初始位置。

(4)   *实现提示:每次在多个可走位置中选择一个进行试探,其余未曾试探过的可走位置必须用适当结构妥善管理,以备试探失败时的“回溯”(悔棋)使用。并探讨每次选择位置的“最佳策略”,以减少回溯的次数。

 

需求分析

1、任务:(一):设置一个含有{x,y,di}变量的结构体。

          定义马向八个方向走的所在位置坐标的变化

int htrx[lenx]={-2,-1,1,2,2,1,-1,-2};

                      int htry[leny]={1,2,2,1,-1,-2,-2,-1};

      (二):初始化数组mata[8][8],全部赋为0。

     (三):判断该位置是否能走(是否已走过,或超出8X8的矩阵)

     (四)对马走的下一个可能方向按一定顺序进行处理。将马可能走的下一个方向按照下下个方向能走的度进行从小到大的排序,并且压入栈中(不能通过的标记为-1)

     (五):处理棋盘。马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入8X8的方阵输出之

定义curstep=1,mata[x][y]=1;((x,y)为用户输入的初始数据)

判断path是否为空,

若不为空,

判断path的栈顶元素的di是否小于0

   若di小于0,退栈。

 否则若mata[x][y]>0((x,y)为栈顶元素的坐标)        mata[x][y]=0(清除走过痕迹)

   Curstep--;步伐值减一

   出栈

否则

   mata[x][y]=++curstep;对马走过的位置进行标记

   根据此位置,重新对马走的下一个可能方向进行排序。

                    若已走完64个位置

                        输出“马在此位置能走遍全部的格子”

                        则打印mata[8][8]数组

               若path为空

                   则输出“马在此位置不能走遍全部的格子”

             

        

测试数据:

在8乘8的矩阵中输出1~64的数,且没有重复的。

#include<iostream>
using namespace std;
#include<stack> 
#define lenx 8
#define leny 8
#define num  lenx*leny
struct Data
{
  int x;
  int y;
  int di;//0~7
};
        
class  MaTa
{
       public:
              MaTa();
              ~MaTa();
			  bool Pass(Data );
			  void Sort(Data );
              Post GetNext(Data,int);//找下一个最优点的位置
              bool Deal(Post );//处理棋盘
              void Print();//输出结果 
       private:
               int **mata; //马踏棋盘数组 
			   int usenum;
                };

  MaTa::MaTa()
  {   
              mata=new int*[lenx];
              for(int i=0;i<lenx;i++)
              {
				  mata[i]=new int[leny];
					  for(int j=0;j<leny;j++)
				            mata[i][j]=0;//表赋空 
			  }
              }

  MaTa::~MaTa()
{
	for (int i = 0; i < lenx; i++)
		if (mata[i] != NULL)
			delete [] mata[i];
	if (mata != NULL)
		delete[] mata;
}
 
 bool MaTa::Pass(Data c)
 {
 return (c.x>-1 && c.x<8 && c. y>-1 && c.y<8 && mata[c.x][c.y]==0);
 }

 void MaTa::Sort(Data c)
{
	    usenum=lenx;
	    int  htrx[lenx]={-2,-1,1,2,2,1,-1,-2};
        int  htry[leny]={1,2,2,1,-1,-2,-2,-1};
        int k,temp;
        Post newseat;
        int du[lenx];
        for(int i=0;i<lenx;i++)
        {
           k=0;
           newseat.x=c.x+htrx[i];
           newseat.y=c.y+htry[i];
              if(Pass(newseat)) 
                  for(int j=0;j<leny;j++)
                   { 
                           newseat.x+=htrx[j];
                           newseat.y+=htry[j];
                       if(Pass(newseat))
                             k++;              
				  }
			  else 
				  usenum--;

			  du[i]=k;
		}

       for(int i=0;i<usenum-1;i++)
		   for(int j=i;j<usenum;j++)
			    if(du[j]<du[j+1])
				{
					temp=htrx[j];
	                htrx[j]=htrx[j+1];
	                htrx[j+1]=temp;

					temp=htry[j];
	                htry[j]=htry[j+1];
	                htry[j+1]=temp;

				}
    }

 Post MaTa::GetNext(Data c,int di)//找下一个点位置-----------------------------------------------
   {
           Sort(c);
	       c.x+=htrx[di];
		   c.y+=hrty[di];
            return c; 
 }

        
   bool MaTa::Deal(Data start)//处理棋盘 ---------------------------------------------------
   {
	     int curstep=1; //足迹
         stack<Data> path(num);
         Data curpos; //当前位置的坐标 
         Data e; 
		 e.di=0;
		 curpos=start;  
             do{
                 if( Pass(curpos))
                  {
					   mata[curpos.x][curpos.y]=curstep++;
					   e.seat.x=curpos.x;
					   e.seat.y=curpos.y;
					   e.di=-1;
                       path.Push(e);
                       if(curstep==num)  
						   return true;
					   else
					     curpos=GetNext(curpos,e.di);                      
                                    } 
                 else
                  {    
					      e=path.top();
                          path.pop();
					      curstep--; 
						  while(e.di==usenum && !path.empty()){
						  mata[e.seat.x][e.seat.y]=0;
						  e=path.top();
						  curdu=e.di+1;
						  path.pop();
						  curstep--;
						  curpos.x=e.seat.x;
						  curpos.y=e.seat.y;
                      
					  }
					  if(e.di<usenum){
                                        e.di++;
										path.push(e);
										curstep++;
									    curpos=GetNext(curpos,e.di);
                                }
                                     }
				
			 } while(!path.empty());
     return false;
    
    }
   
   void MaTa::Print()//输出结果-------------------------------------------------------------
   {
     for(int i=0;i<lenx;i++)
	 {

       for(int j=0;j<leny;j++)
        if(mata[i][j]>=0 && mata[i][j]<10)
        cout<<"   "<<mata[i][j];
        else
        cout<<"  "<<mata[i][j];
		cout<<endl;
        } 
   }
   int main()
   {
       MaTa m_mata;
       Data start;
       cout<<"请输入开始位置的坐标: "<<endl;
	   cin>>start.x>>start.y;
      if( m_mata.Deal(start))
         { 
          cout<<"马走遍全部64个格子"<<endl;
          m_mata.Print();
          } 
          else
          cout<<"马不能走遍所有的格子"<<endl;
	  system("pause");
	  return 0;
       }




  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值