伊莉討論區

標題: 騎士周游問題的代碼 [打印本頁]

作者: zhazhaniu2    時間: 2009-8-26 10:58 AM     標題: 騎士周游問題的代碼

騎士周游問題:給出m×n的棋盤,還有給出馬的起始位置,求出一條路線,使馬能跳完棋盤上所有格子以后回到起點

我們上學期的一個作業,優化了很久呢~算3000×3000的棋盤分配好內存后只需要二十秒左右可以求得一個解,不過要爆棧,不爆棧的話因為是遞歸的,所以只能算到78×78的棋盤(不知道什么是爆棧和怎么爆棧的話google一下吧~呵呵呵~)

代碼貼上來,給需要的人做個參考吧~

  1. #include <iostream>
  2. #include <fstream>
  3. #include<iomanip>
  4. #include <algorithm>
  5. using namespace std;
  6. bool finish(int i,int j);
  7. int startx,starty,m,n,grid[3010][3010],endstep,nowi,nowj;
  8. struct Point
  9. {
  10. int x,y;
  11. }pos[9];
  12. struct P
  13. {
  14. int No,mark;
  15. };
  16. bool less_2(const P & p1, const P & p2)
  17. {
  18. if(p1.mark<p2.mark || p1.No==-1 || p2.No==-1)
  19.   return p1.mark<p2.mark;
  20. else if(p1.mark==p2.mark)return (pos[p1.No].x+nowi-m/2)*(pos[p1.No].x+nowi-m/2)+(pos[p1.No].y+nowj-n/2)*(pos[p1.No].y+nowj-n/2)>(pos[p2.No].x+nowi-m/2)*(pos[p2.No].x+nowi-m/2)+(pos[p2.No].y+nowj-n/2)*(pos[p2.No].y+nowj-n/2);
  21. else return 0;
  22. }
  23. void output2()
  24. {
  25. int i,j;
  26. ofstream a("c:\\a.txt");
  27. for(i=1;i<=m;++i)
  28. {
  29.   for(j=1;j<=n;++j)
  30.   {
  31.    a<<grid[i][j]<<' ';
  32.   }
  33.   a<<endl;
  34. }
  35. a.close();
  36. }
  37. void output()
  38. {
  39. int i,j;
  40. for(i=1;i<=m;++i)
  41. {
  42.   for(j=1;j<=n;++j)
  43.   {
  44.    cout<<setw(3)<<grid[i][j]<<' ';
  45.   }
  46.   cout<<endl;
  47. }
  48. }
  49. void init()
  50. {
  51. pos[8].x=1,pos[8].y=-2;
  52. pos[1].x=2,pos[1].y=-1;
  53. pos[2].x=2,pos[2].y=1;
  54. pos[7].x=1,pos[7].y=2;
  55. pos[3].x=-1,pos[3].y=2;
  56. pos[6].x=-2,pos[6].y=1;
  57. pos[5].x=-2,pos[5].y=-1;
  58. pos[4].x=-1,pos[4].y=-2;
  59. cout<<"請輸入棋盤大小(m n):";
  60. cin>>m>>n;
  61. cout<<"請輸入馬的起始坐標(x y):";
  62. cin>>startx>>starty;
  63. endstep=m*n;
  64. memset(grid,0,sizeof(grid));
  65. }
  66. int predict(int i,int j)
  67. {
  68. int k,prei,prej,result=0;
  69. for(k=1;k<=8;++k)
  70. {
  71.   prei=i+pos[k].x;
  72.   prej=j+pos[k].y;
  73.   if(prei>0 && prei<=m && prej>0 && prej<=n && grid[prei][prej]==0)++result;
  74. }
  75. return result;
  76. }
  77. void mark(int i,int j,P *p,int step)
  78. {
  79. int k,prei,prej;
  80. for(k=1;k<=8;++k)
  81. {
  82.   prei=i+pos[k].x;
  83.   prej=j+pos[k].y;
  84.   if(prei>0 && prei<=m && prej>0 && prej<=n && grid[prei][prej]==0){p[k-1].mark=predict(prei,prej);p[k-1].No=k;}
  85.   else {p[k-1].No=-1;p[k-1].mark=9999;}
  86. }
  87. sort(p,p+8,less_2);
  88. }
  89. bool finish(int i,int j)
  90. {
  91. int k,prei,prej;
  92. for(k=1;k<=8;++k)
  93. {
  94.   prei=i+pos[k].x;
  95.   prej=j+pos[k].y;
  96.   if(prei>0 && prei<=m && prej>0 && prej<=n && grid[prei][prej]==1)return 1;
  97. }
  98. return 0;
  99. }
  100. bool jump(int i,int j,int step)
  101. {
  102. int k;
  103. grid[i][j]=step;
  104. nowi=i,nowj=j;
  105. P p[8];
  106. mark(i,j,p,step);
  107. if(step==endstep)
  108. {
  109.   if(finish(i,j))return 1;
  110.   else grid[i][j]=0;return 0;
  111. }
  112. else
  113. {
  114.   for(k=0;p[k].mark<9999;++k)
  115.   {
  116.    if(jump(i+pos[p[k].No].x,j+pos[p[k].No].y,step+1))return 1;
  117.   }
  118.   grid[i][j]=0;
  119. }
  120. return 0;
  121. }
  122. void transf(int a,int b)
  123. {
  124. int i,j,base=grid[a][b];
  125. for(i=1;i<=m;++i)
  126.   for(j=1;j<=n;++j)
  127.    if(grid[i][j]>=base)grid[i][j]-=(base-1);
  128.    else grid[i][j]=grid[i][j]-base+n*n+1;
  129. }

  130. int main(int argc, char* argv[])
  131. {
  132. init();
  133. if(jump(m/2,n/2,1))
  134. {
  135.   transf(startx,starty);
  136.   output();
  137. }
  138. else cout<<"No!"<<endl;
  139. return 0;
  140. }
複製代碼





歡迎光臨 伊莉討論區 (http://godaddy01.mobile.wahas.com/) Powered by Discuz!