回溯
#include <iostream> //sicily 1152. 简单的马周游问题
#include<stdio.h>
using namespace std;
int vis[10][10],path[100],rear;
int arr[8][2]={{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}};
void backtrace(int s,int t)
{
int m,n;
for(int i=0;i<8;++i)
{
m=s+arr[i][0];n=t+arr[i][1];
if(m>=0&&m<=4&&n>=0&&n<=5&&vis[m][n]==0)
{
path[rear++]=m*6+n+1;
vis[m][n]=1;
if(rear==30)
{
for(int j=0;j<rear;++j)
cout<<path[j]<<" ";
cout<<endl;
return ;
}
backtrace(m,n);
if(rear==30)
return ;
//如果没有if(rear==30)return; 那么执行完 backtrack(m,n); 后即使rear==30仍然会rea--;于是会继续执行下去
//那么最终结果是输出全部的周游路径
vis[m][n]=0;
rear--;
}
}
}
int main()
{
int a;
while(cin>>a&&a!=-1)
{
fill(&vis[0][0],&vis[9][9],0); //memset()函数需要包括#include<memory.h>
rear=0;
int m=(a-1)/6,n=a-m*6-1;
vis[m][n]=1;
path[rear++]=a;
backtrace(m,n);
}
return 0;
}
//sicily 1153
//与sicily 1152 题意一样,但数据量大很多,直接搜肯定会TLE,
//可以先搜索扩展性最差的点,这样能减少路径数
#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<memory.h>
using namespace std;
int vis[10][10],path[100],rear;
int arr[8][2]={{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}};
bool region(int x,int y)
{
return x>=0&&x<=7&&y>=0&&y<=7;
}
int expand(int m,int n)
{
int s=0,mm,nn;
for(int i=0;i<8;++i)
{
mm=m+arr[i][0];nn=n+arr[i][1];
if(region(mm,nn)&&vis[mm][nn]==0)
s++;
}
return s;
}
struct node
{
int x,y;
bool operator<(const node& o)const
{
return expand(x,y)<expand(o.x,o.y);
}
}pos[8];
void backtrace(int s,int t)
{
int m,n,i,j=0;
for(i=0;i<8;++i)
{
m=s+arr[i][0];n=t+arr[i][1];
if(region(m,n)&&vis[m][n]==0)
pos[j].x=m,pos[j++].y=n;
}
sort(pos,pos+j);
for(i=0;i<j;++i)
{
path[rear++]=pos[i].x*8+pos[i].y+1;
vis[pos[i].x][pos[i].y]=1;
if(rear==64)
{
for(int k=0;k<rear;++k)
cout<<path[k]<<" ";
cout<<endl;
return ;
}
backtrace(pos[i].x,pos[i].y);
if(rear==64)
return ;
vis[pos[i].x][pos[i].y]=0;
rear--;
}
}
int main()
{
int a;
while(cin>>a&&a!=-1)
{
memset(vis,0,sizeof(vis));
rear=0;
int m=(a-1)/8,n=a-m*8-1;
vis[m][n]=1;
path[rear++]=a;
backtrace(m,n);
}
return 0;
}