伊莉討論區
標題:
騎士周游問題的代碼
[打印本頁]
作者:
zhazhaniu2
時間:
2009-8-26 10:58 AM
標題:
騎士周游問題的代碼
騎士周游問題:給出m×n的棋盤,還有給出馬的起始位置,求出一條路線,使馬能跳完棋盤上所有格子以后回到起點
我們上學期的一個作業,優化了很久呢~算3000×3000的棋盤分配好內存后只需要二十秒左右可以求得一個解,不過要爆棧,不爆棧的話因為是遞歸的,所以只能算到78×78的棋盤(不知道什么是爆棧和怎么爆棧的話google一下吧~呵呵呵~)
代碼貼上來,給需要的人做個參考吧~
#include <iostream>
#include <fstream>
#include<iomanip>
#include <algorithm>
using namespace std;
bool finish(int i,int j);
int startx,starty,m,n,grid[3010][3010],endstep,nowi,nowj;
struct Point
{
int x,y;
}pos[9];
struct P
{
int No,mark;
};
bool less_2(const P & p1, const P & p2)
{
if(p1.mark<p2.mark || p1.No==-1 || p2.No==-1)
return p1.mark<p2.mark;
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);
else return 0;
}
void output2()
{
int i,j;
ofstream a("c:\\a.txt");
for(i=1;i<=m;++i)
{
for(j=1;j<=n;++j)
{
a<<grid[i][j]<<' ';
}
a<<endl;
}
a.close();
}
void output()
{
int i,j;
for(i=1;i<=m;++i)
{
for(j=1;j<=n;++j)
{
cout<<setw(3)<<grid[i][j]<<' ';
}
cout<<endl;
}
}
void init()
{
pos[8].x=1,pos[8].y=-2;
pos[1].x=2,pos[1].y=-1;
pos[2].x=2,pos[2].y=1;
pos[7].x=1,pos[7].y=2;
pos[3].x=-1,pos[3].y=2;
pos[6].x=-2,pos[6].y=1;
pos[5].x=-2,pos[5].y=-1;
pos[4].x=-1,pos[4].y=-2;
cout<<"請輸入棋盤大小(m n):";
cin>>m>>n;
cout<<"請輸入馬的起始坐標(x y):";
cin>>startx>>starty;
endstep=m*n;
memset(grid,0,sizeof(grid));
}
int predict(int i,int j)
{
int k,prei,prej,result=0;
for(k=1;k<=8;++k)
{
prei=i+pos[k].x;
prej=j+pos[k].y;
if(prei>0 && prei<=m && prej>0 && prej<=n && grid[prei][prej]==0)++result;
}
return result;
}
void mark(int i,int j,P *p,int step)
{
int k,prei,prej;
for(k=1;k<=8;++k)
{
prei=i+pos[k].x;
prej=j+pos[k].y;
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;}
else {p[k-1].No=-1;p[k-1].mark=9999;}
}
sort(p,p+8,less_2);
}
bool finish(int i,int j)
{
int k,prei,prej;
for(k=1;k<=8;++k)
{
prei=i+pos[k].x;
prej=j+pos[k].y;
if(prei>0 && prei<=m && prej>0 && prej<=n && grid[prei][prej]==1)return 1;
}
return 0;
}
bool jump(int i,int j,int step)
{
int k;
grid[i][j]=step;
nowi=i,nowj=j;
P p[8];
mark(i,j,p,step);
if(step==endstep)
{
if(finish(i,j))return 1;
else grid[i][j]=0;return 0;
}
else
{
for(k=0;p[k].mark<9999;++k)
{
if(jump(i+pos[p[k].No].x,j+pos[p[k].No].y,step+1))return 1;
}
grid[i][j]=0;
}
return 0;
}
void transf(int a,int b)
{
int i,j,base=grid[a][b];
for(i=1;i<=m;++i)
for(j=1;j<=n;++j)
if(grid[i][j]>=base)grid[i][j]-=(base-1);
else grid[i][j]=grid[i][j]-base+n*n+1;
}
int main(int argc, char* argv[])
{
init();
if(jump(m/2,n/2,1))
{
transf(startx,starty);
output();
}
else cout<<"No!"<<endl;
return 0;
}
複製代碼
歡迎光臨 伊莉討論區 (http://godaddy01.mobile.wahas.com/)
Powered by Discuz!