问题描述:http://acm.jlu.edu.cn/joj/showproblem.php?pid=2771&off=2700
Problem B: Chinese KnightThere are different pieces In Chinese Chess, such as General, Advisor, Elephant, Knight, Chariot, Cannon and Solider.The knights(horses) are labeled 馬. They begin the game next to the elephants. A knight moves and captures one point orthogonally and then one point diagonally away from its former position, a move which is traditionally described as being like the Chinese character „日‟. The knight does not jump as the knight does in Western chess. Thus, if there were a piece lying on a point one point away horizontally or vertically from the horse, then the horse's path of movement is blocked and it is unable to move in that direction. Note, however, that a piece two points orthogonally or a single point away diagonally would not impede the movement of the horse. Blocking a horse is also known as "hobbling the horse's leg". The figure 2.1 illustrates the horse's movement.Since knight can be blocked, it is sometimes possible to trap the opponent's horse. It is possible for one player's knight to attack the opponent's horse while the opponent's knight is blocked from attacking, as seen in the figure 2.2.Figure 2.1 Movement of knight Figure 2.2 Asymmetric movementOn a n*n grid chessboard, a Chinese knight want to visit each placement exactly once. This is just like traditional “Knight‟s tour problem”. Unfortunately, there are some obstacles on the placement. The knight can‟t reach it‟s placement and maybe blocked by these obstacles. On the other hand, it is also fortunate, the number of all possible paths is decreased rapidly.Our knight will always begin his tour at top-left. The number of obstacles is between 1 and 5. You should calculate the number of valid paths. It is not necessary that the knight return his starting position. And all the obstacles is excluded from the path.6th Jilin Province Collegiate Programming Contest - Mar 20, 2012InputThe first line of each case are three integers m, n and k. m and n are the size of chessboard (m, n<=6) and k is indicated the number of obstacles. k is -1 means the end of input.The next k lines are two numbers that are coordinates of each obstacle (startingfrom 1).
OutputFor each case, output the number of all successful paths.
Sample Input5 5 22 35 55 5 -1
Sample Output2
HintOne of possible path of the sample input is described as follows. Each number is the step of knight except -1 means obstacle.1 18 13 6 2312 7 -1 19 1417 2 9 22 58 11 4 15 203 16 21 10 -1
参考代码:
#include<iostream>
using namespace std;
int cB[7][7];
int mark[7][7];
int m,n,k;
int wn;
void initial()
{
for(int i=0;i<7;i++)
for(int j=0;j<7;j++)
{
cB[i][j]=0;
mark[i][j]=0;
}
}
void refresh(int max)
{
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
if(cB[i][j]>max)
{
cB[i][j]=0;
mark[i][j]=0;
}
}
bool check()
{
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
if(cB[i][j]==0)
return false;
return true;
}
void fWay(int px,int py,int no)
{
cB[px][py]=no;
int flag=false;
while(mark[px][py]<8)
{
if(flag)
{
refresh(cB[px][py]);
flag=false;
}
if(mark[px][py]==0)
{
mark[px][py]++;
if((px-2)>0&&(py-1)>0&&cB[px-1][py]!=-1&&cB[px-2][py-1]==0)
{
fWay(px-2,py-1,++no);
flag=true;
}
}
else if(mark[px][py]==1)
{
mark[px][py]++;
if((px-1)>0&&(py-2)>0&&cB[px][py-1]!=-1&&cB[px-1][py-2]==0)
{
fWay(px-1,py-2,++no);
flag=true;
}
}
else if(mark[px][py]==2)
{
mark[px][py]++;
if((px+1)<=m&&(py-2)>0&&cB[px][py-1]!=-1&&cB[px+1][py-2]==0)
{
fWay(px+1,py-2,++no);
flag=true;
}
}
else if(mark[px][py]==3)
{
mark[px][py]++;
if((px+2)<=m&&(py-1)>0&&cB[px+1][py]!=-1&&cB[px+2][py-1]==0)
{
fWay(px+2,py-1,++no);
flag=true;
}
}
else if(mark[px][py]==4)
{
mark[px][py]++;
if((px+2)<=m&&(py+1)<=n&&cB[px+1][py]!=-1&&cB[px+2][py+1]==0)
{
fWay(px+2,py+1,++no);
flag=true;
}
}
else if(mark[px][py]==5)
{
mark[px][py]++;
if((px+1)<=m&&(py+2)<=n&&cB[px][py+1]!=-1&&cB[px+1][py+2]==0)
{
fWay(px+1,py+2,++no);
flag=true;
}
}
else if(mark[px][py]==6)
{
mark[px][py]++;
if((px-1)>0&&(py+2)<=n&&cB[px][py+1]!=-1&&cB[px-1][py+2]==0)
{
fWay(px-1,py+2,++no);
flag=true;
}
}
else if(mark[px][py]==7)
{
mark[px][py]++;
if((px-2)>0&&(py+1)<=n&&cB[px-1][py]!=-1&&cB[px-2][py+1]==0)
{
fWay(px-2,py+1,++no);
flag=true;
}
}
}
refresh(cB[px][py]);
if(check())
wn++;
}
int main()
{
cin>>m>>n>>k;
while(k!=-1)
{
initial();
for(int i=0;i<k;i++)
{
int x,y;
cin>>x>>y;
cB[x][y]=-1;
}
wn=0;
cB[1][1]=1;
fWay(1,1,1);
cout<<wn<<endl;
cin>>m>>n>>k;
}
return 0;
}
说明:由于本人菜鸟,代码虽然实现了,但是不好,时间空间占用超多,稍后会给出改进!