记得上次那个马踏棋盘吗?我本着奋斗到底的原则,写了一个 回溯的程序.我确实还真没见过回溯的,实在是见识浅薄.
同样,问题不少,倒霉一路.不过最后总算是成功了.同样计算所有路径仍然遥不可及,不过却有一个欣喜的发现,求一解的情况,在递归8X8瞬时不能的情况下,回溯竟然可以马上出来!I LOVE THIS ALGORITHM!
#include <stdio.h>
bool a[8][8];//走过的标记
int b[64][2];//栈
int c[64]={0};
int deltai[]={2,1,-1,-2,-2,-1,1,2};
int deltaj[]={1,2,2,1,-1,-2,-2,-1};
int HorseMove(int x,int y){
int k=0,i,j,sum=0;
for(i=0;i<64;i++){b[i][0]=b[i][1]=-1;c[i]=0;}
for(i=0;i<8;i++){for(j=0;j<8;j++){a[i][j]=false;}}
a[x][y]=true;
b[0][0]=x;
b[0][1]=y;
while(true){
while(c[k]<8&&c[k]>=0){
if(k>=63) {
//sum++;
//break;
return 1;
}
x=b[k][0]+deltai[c[k]];
y=b[k][1]+deltaj[c[k]];
if(x>=0&&x<8&&y>=0&&y<8&&a[x][y]==false){
a[x][y]=1;
k++;
b[k][0]=x;
b[k][1]=y;
}
else{ //换种跳动方式
c[k]++;
}
}
//如果某一位置已经无路可走,则脱离循环,到此步来退栈
if(k==0) break;
else{
a[b[k][0]][b[k][1]]=false;
b[k][0]=-1;
b[k][1]=-1;
c[k--]=0;
c[k]++;
}
}
return sum;
}
int main(){
printf("%d/n",HorseMove(0,0));
return 0;
}
Given that we have a n*m (2 ≤ n ≤ 50, 2 ≤m ≤ 50) chessboard, a knight moves to the square that is on the opposite corner of a 2*3 rectangle from its current position. Assuming that a knight can only move in four directions from left to right.
Your task is here: Given n, m the start point and the end point, try to find out the number of all the possible path from the start point to the end point.
Input
Each input consists of two blocks. The first block contains two integers: n and m; the second block contains four intergers a, b, c and d, which stand for the start point (a,b) and the end point (c,d) (Note: a ≤ c). The block where both two numbers in the first block is "0 0" denotes the end of the input.
Output
The output consists of lines corresponding to the blocks of the input except the terminating block. Each such line contains the answer which gives the number of path from the start point to the end point.
Sample Input
Sample Output
Note the chessboard points' location is beginning from 1!
我之所以这么在乎马踏棋盘,多少是因为其经典性,再加上这到题,这是我看的第三道题......所以我希望能解出它来.
经过对回溯解法简单修改,就可以得到相应程序.
#include <stdio.h>
#define M 40 //行
#define N 40 //列
bool a[M][N];//走过的标记
int b[M*N][2];//栈
int c[M*N]={0};
int deltai[]={2,1,-1,-2};
int deltaj[]={1,2,2,1};
int Knight(int x,int y,int w,int z){
int k=0,sum=0,i,j;
for(i=0;i<M*N;i++){b[i][0]=b[i][1]=-1;c[i]=0;}
for(i=0;i<M;i++){for(j=0;j<N;j++){a[i][j]=false;}}
a[x][y]=true;
b[0][0]=x;
b[0][1]=y;
while(true){
while(c[k]<4&&c[k]>=0){
if(x==w&&y==z){
sum++;
break;
}
x=b[k][0]+deltai[c[k]];
y=b[k][1]+deltaj[c[k]];
if(x<=w&&x>=0&&y>=0&&y<M&&a[x][y]==false){
a[x][y]=1;
k++;
b[k][0]=x; //x,y入栈
b[k][1]=y;
}
else{
c[k]++;
}
}
if(k==0) break;
else{
a[b[k][0]][b[k][1]]=false;
b[k][0]=-1;
b[k][1]=-1;
c[k--]=0;
c[k]++;
}
}
return sum;
}
int main(){
printf("%d/n",Knight(1,1,32,30));
return 0;
}
我最在乎的是速度.虽然这答案输入不合乎规范,输出答案也不对,同样也不是从1-1而是从0-0定义的,但起码速度快了,摸到门了......
题目给的两个输入输出范例就不合标准,我现在也不明白,为什么1,5,3,5会是两种走法,即使是我把X,Y顺序搞倒了,也有Note: a ≤ c啊...不管了,就算我对了吧,啊?...
我的骑士啊,你是我的希望啊!带领我上阵杀敌,取得胜利吧,虽然道路还很遥远...
1 2
3 3 2 2 2 2 10 10 1 5 3 5 0 0