Problem A:祝福
【问题描述】
得知Atlantis即将沉没的消息以后,King决定把他的人民送到安全的国外去。但是码头已经废弃很多很多年了。码头前有一个迷宫,国王的骑士只身闯入了这个迷宫……
骑士在迷宫的出口遇到了不明生物的袭击!骑士因为是单独作战,所以很快便招架不住了,他的大马被打得奄奄一息(。。。)
这个时候,迷宫中的两座石像(一个是猫,一个是天使。(!!!!!))里放出了无数锋利的刀片,把不明生物全部杀死,骑士当场晕倒在地。等他醒来,发现马已经死了,手上多了一个戒指,上面写着:
“这个戒指会帮助你逃脱。它赋予了神奇的力量。有了它,每次移动如果是只要|x-x1|+|y-y1|<=P(P在输入文件中给出),且(x1, y1)不是障碍物,你就能实现(x, y) -> (x1, y1)的移动!”(Angel暗自想:还有这么心黑的……)
迷宫为n*m(0<n,m<=20)的矩阵。骑士从(n, m)到(1, 1)。问:
在戒指的帮助下,骑士最少要多少步才能回到入口?在步数最少的前提下,总共有多少种办法到达入口?注意,骑士不会傻到一直停留在原地不动。
【输入文件】
第1行3个整数,n, m, P,分别代表迷宫大小和移动范围
以后n行,每行m个数,代表了迷宫,其中0代表可通,1代表不能通过。
【输出文件】
两个整数,用空格分开,分别代表最少到达入口的步数和路径的数目。假设一定能够达到入口。
【样例输入】
2 2 1
0 0
1 0
【样例输入】
2 1
本来纯用BFS的,结果死活不对,就用DFS+BFS了,DFS很顺~幸好数据量不大,要不就不好玩了。
我的搜索是以那个点为中心,画个图就知道了,是一个四边形,画下就好~不过这个循环让我好纠结,还不如都判断一遍简单。。
#include <stdio.h> #include <stdlib.h> #include <queue> #include <iostream> #include <limits.h> using namespace std; typedef struct{ int x,y; }NODE; queue<NODE> Q; int map[25][25],sum,mmin,p,m,n; int flag[25][25],cou; void DFS(int x,int y) { int c = -p; if( x == y && x == 1 && cou == mmin ) sum++; for(int k=y-p; k<=y+p; k++) { if( k >= 1 && k <= n ) { int cc = abs(c); for(int i=x-(p-cc); i<=x+(p-cc); i++) { if( i >= 1 && i <= m && !map[i][k] && !flag[i][k] ) { cou++; flag[i][k] = 1; DFS(i,k); flag[i][k] = 0; cou--; } } } c++; } } int main() { int count[25][25]; while( scanf("%d %d %d",&n,&m,&p)!=EOF ) { sum = 0; for(int i=1; i<=n; i++) for(int k=1; k<=m; k++) scanf("%d",&map[i][k]); NODE a; a.x = n; a.y = m; memset(flag,0,sizeof(flag)); for(int i=1; i<=n; i++) for(int k=1; k<=m; k++) count[i][k] = 10000; count[n][m] = 0; Q.push(a); while( !Q.empty() ) { int c = -p; NODE b = Q.front(); Q.pop(); int x = b.x, y = b.y; for(int k=y-p; k<=y+p; k++) { if( k >= 1 && k <= n ) { int cc = abs(c); for(int i=x-(p-cc); i<=x+(p-cc); i++) { if( i >= 1 && i <= m && !map[i][k] ) { NODE a; a.x = i; a.y = k; if( count[i][k] > count[x][y] ) count[i][k] = count[x][y] + 1; if( i == 1 && k == 1 ) goto end; Q.push(a); } } } c++; } } end: mmin = count[1][1]; while( !Q.empty() ) Q.pop(); DFS(n,m); printf("%d %d/n",mmin,sum); } return 0; }