描述
You are playing one game called "Number Maze". The map of an example is shown in the following figure.
In the map, there are N*N+2 cells. When the game starts, you stay the top-left cell and you target is to reach the bottom-right cell with fewest number of moves. At the first step, you must move to the right of the start cell. After that, you can move to any cell (left, right, up or down, but can not move diagonally) if the target cell can be divided by the sum of the previous two numbers. However, you should never move backwards. For example, at first, you stay at the "2" cell, and you must move to the "6" cell, then have two selections "8" or "4" because (2+6)/8=1 and (2+6)/4=2, you can not move back to the "2" cell at this step although (2+6)/2=4. One possilbe solution is 2->6->8->7->5->3->4->7->11->2->13, and the total number of moves is 10.
Another solution is also legal but has longer moves:
2->6->8->7->5->3->4->7->5->3->4->7->11->2->13
输入
Thare are at most 20 cases. The first line of each case has three integers N<=10, S and T, which N indicates the dimension of the map, S and T indicate the number in the start and target cell. Then follows N lines and each line has N positive integers which indicate each number in the N*N cells.
There has one blank line after each case and you can assume that the total number of all cells is no larger than 1000000.
The inputs are ended with End of File.
输出
Each case outputs the fewest number of moves or "Impossible" if you can not reach the target cell per line.
样例输入
3 2 13
6 4 3
8 7 5
2 11 2
样例输出
10
先解释下题意:给你应该N*N的矩阵。矩阵的每个位置都有值,然后在矩阵的左上和右下都有一个位置。叫我们找一条走的步数最小的路可以从左上走到右下。
可以上下左右走。。。但是每次不可以往回走。都是下一步要走的位置的值要可以被你所在位置和上个位置的值的和整除。
有二个坑点。。。不能往回走。和可能会产生回路。
下面是代码:
#include<stdio.h>
#include<algorithm>
#include<queue>
using namespace std;
int MAP[20][20];
struct A
{
int x,y,side;
int fan,z1,z2;
bool operator ==(const A &a)
{
return ((a.x==x)&&(a.y==y)&&(a.side==side)&&(a.fan==fan)&&(a.z1==z1)&&(a.z2==z2));
}
};
int N,S,T;
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int bfs()
{
queue<A>Q;
A M[110];//用于判断是不是产生了回路。
int len=0;
A d;
d.x=1;
d.y=1;
d.fan=0;
d.side=1;
d.z1=S;
d.z2=MAP[1][1];
Q.push(d);
while(!Q.empty())
{
d=Q.front();
Q.pop();
bool f=0;
for(int i=0;i<len;i++)
if(M[i]==d)
{
f=1;break;
}
if(f)continue;
else
{
M[len++]=d;
}
if(d.x==N&&d.y==N+1)return d.side;
for(int i=0;i<4;i++)
{
A D=d;
D.x+=dir[i][0];
D.y+=dir[i][1];
if(D.x>=1&&D.x<=N&&D.y>=1&&d.y<=N+1)
{
if(D.y==N+1&&D.x!=N)continue;
if((D.z1+D.z2)%MAP[D.x][D.y]!=0)continue;//保证整除
if((D.fan+2)%4==i)continue;//保证不往回走
// printf("%d %d %d %d %d++++\n",D.x,D.y,D.fan,D.z1,D.z2);
D.z1=D.z2;
D.fan=i;
D.z2=MAP[D.x][D.y];
D.side++;
Q.push(D);
}
}
}
return -1;
}
int main()
{
while(scanf("%d",&N)!=EOF)
{
scanf("%d %d",&S,&T);
for(int i=1;i<=N;i++)
{
for(int j=1;j<=N;j++)
scanf("%d",&MAP[i][j]);
}
MAP[1][0]=S;
MAP[N][N+1]=T;
int ans=bfs();
if(ans==-1)puts("Impossible");
else printf("%d\n",ans);
}
}