马的周游问题

来源:互联网 发布:c语言连接字符串 编辑:程序博客网 时间:2024/05/15 08:08

不剪枝的话就是最多来算是 860次计算,但是由于只需要找到一个合理的的解,我们可以优先的搜索分支最少的状态,这样就可以极大的减少计算量,大约每次的分支数比4还要小。
将可能的8中跳法,用编码的方式给出,极大地减少了代码量。
注意dfs的书写,最起初有个8个选择,当8个选择中有一个正确的时候,就可以结束判断了,当8个选择全部都错误的时候就可以结束判断了。
注意最终状态的判读,不然会出现无穷次的计算。

#include <iostream>#include <cmath>#include <cstring>#include <vector>#include <algorithm>using namespace std;int const maxn = 10;int map[maxn][maxn];int vis[maxn][maxn];int ans[maxn*maxn];int dr[] = {-1,-2,-2,-1,1,2,2,1};int dc[] = {-2,-1, 1 ,2,2,1,-1,-2};struct point {    int r,c,val;};bool isin(int r,int c) {    return r>=0&&r<8&&c>=0&&c<8;}bool cmp(point a,point b) {    return a.val<b.val;} bool  dfs(int r,int c,int count) {    if(count==63) {      for (int i=0;i<64;i++) cout<<ans[i]+1<<" ";        cout<<endl;        return true;    }     else {        vector<point> V;        for (int i=0;i<8;i++) {            point t;            t.r = r+dr[i];            t.c = c+dc[i];            t.val = 0;          if(isin(t.r,t.c)&&!vis[t.r][t.c]) {             for (int j=0;j<8;j++) {                int nr = t.r+dr[j];                int nc = t.c+dc[j];                if(isin(nr,nc)&&!vis[nr][nc]) t.val++;             }              V.push_back(t);           }        }        sort(V.begin(),V.end(),cmp);        for (int i=0;i<V.size();i++) {            ans[++count] = map[V[i].r][V[i].c];            vis[V[i].r][V[i].c]=1;            if(dfs(V[i].r,V[i].c,count)) return true;             count--;            vis[V[i].r][V[i].c]=0;        }        return false;    }}int main() { int k=0; for (int i=0;i<8;i++)  for (int j=0;j<8;j++) map[i][j]=k++;  int a;  while (cin>>a&&a!=-1) {    a--;    memset(vis,0,sizeof(vis));    vis[a/8][a%8] = 1;    ans[0]=a;    dfs(a/8,a%8,0);    cout<<endl;  }}    
0 0