161. [USACO Oct07] 障碍训练场
★☆ 输入文件:obstacle.in
输出文件:
obstacle.out
简单对比
时间限制:1 s 内存限制:128 MB
- 行 1: 一个整数 N
- 行 2..N + 1: 行 i+1 有 N 个字符 ('.', 'x', 'A', 'B'),表示每个点的状态。
- 行 1: 一个整数,最少的转弯次数。
译 By CmYkRgB123
考虑一个 N x N (1 <= N <= 100)的有1个个方格组成的正方形牧场。有些方格是奶牛们不能踏上的,它们被标记为了'x'。例如下图:
. . B x . . x x A . . . . x . . x . . . . . x . .
贝茜发现自己恰好在点A出,她想去B处的盐块添盐。缓慢而且笨拙的动物,比如奶牛,十分讨厌转弯。尽管如此,当然在必要的时候她们还是会转弯的。对于一个给定的牧场,请你计算从A到B最少的转弯次数。开始的时候,贝茜可以使面对任意一个方向。贝茜知道她一定可以到达。
程序名: obstacle
输入
输出
输入样例
3 .xA ... Bx.
输出样例
2
计数BFS
当times<mintimes[y][x][dir]时遍历
当times>=mintimes[y][x][dir]时,times不会减小,因此最小成立
代码
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define INF 999999999
#define MAX_N 101
#define MAX_Q 100000
#define ADD(x) x=(x+1)%MAX_Q
struct QNode
{
int x,y,times;
int dir;
} queue[MAX_Q];
int front,rear;
int aposx,aposy,bposx,bposy;
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int N;
char map[MAX_N][MAX_N];
int mintimes[MAX_N][MAX_N][4];
int maxtimes=INF;
int main()
{
freopen("obstacle.in","r",stdin);
freopen("obstacle.out","w",stdout);
scanf("%d",&N);
for(int i=0;i<N;i++)
{
scanf("%s",map[i]);
char *pFind=strchr(map[i],'A');
if(pFind)
{
aposx=pFind-map[i];
aposy=i;
continue;
}
pFind=strchr(map[i],'B');
if(pFind)
{
bposx=pFind-map[i];
bposy=i;
}
}
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
for(int k=0;k<4;k++) mintimes[i][j][k]=INF;
front=rear=0;
queue[rear]=QNode{aposx,aposy,0,0};
ADD(rear);
mintimes[aposy][aposx][0]=0;
queue[rear]=QNode{aposx,aposy,0,1};
ADD(rear);
mintimes[aposy][aposx][1]=0;
queue[rear]=QNode{aposx,aposy,0,2};
ADD(rear);
mintimes[aposy][aposx][2]=0;
queue[rear]=QNode{aposx,aposy,0,3};
ADD(rear);
mintimes[aposy][aposx][3]=0;
while(front!=rear)
{
QNode q=queue[front];
ADD(front);
if(q.x==bposx && q.y==bposy)
{
if(q.times<maxtimes) maxtimes=q.times;
}
switch(q.dir)
{
case 0:
if(q.times+1<mintimes[q.y][q.x][2])
{
queue[rear]=QNode{q.x,q.y,q.times+1,2};
mintimes[q.y][q.x][2]=q.times+1;
ADD(rear);
}
if(q.times+1<mintimes[q.y][q.x][3])
{
queue[rear]=QNode{q.x,q.y,q.times+1,3};
mintimes[q.y][q.x][3]=q.times+1;
ADD(rear);
}
break;
case 1:
if(q.times+1<mintimes[q.y][q.x][2])
{
queue[rear]=QNode{q.x,q.y,q.times+1,2};
mintimes[q.y][q.x][2]=q.times+1;
ADD(rear);
}
if(q.times+1<mintimes[q.y][q.x][3])
{
queue[rear]=QNode{q.x,q.y,q.times+1,3};
mintimes[q.y][q.x][3]=q.times+1;
ADD(rear);
}
break;
case 2:
if(q.times+1<mintimes[q.y][q.x][0])
{
queue[rear]=QNode{q.x,q.y,q.times+1,0};
mintimes[q.y][q.x][0]=q.times+1;
ADD(rear);
}
if(q.times+1<mintimes[q.y][q.x][1])
{
queue[rear]=QNode{q.x,q.y,q.times+1,1};
mintimes[q.y][q.x][1]=q.times+1;
ADD(rear);
}
break;
case 3:
if(q.times+1<mintimes[q.y][q.x][0])
{
queue[rear]=QNode{q.x,q.y,q.times+1,0};
mintimes[q.y][q.x][0]=q.times+1;
ADD(rear);
}
if(q.times+1<mintimes[q.y][q.x][1])
{
queue[rear]=QNode{q.x,q.y,q.times+1,1};
mintimes[q.y][q.x][1]=q.times+1;
ADD(rear);
}
break;
}
int nx=q.x+dx[q.dir],ny=q.y+dy[q.dir];
if(nx>=0 && nx<N && ny>=0 && ny<N && map[ny][nx]!='x' && q.times<mintimes[ny][nx][q.dir])
{
queue[rear]=QNode{nx,ny,q.times,q.dir};
mintimes[ny][nx][q.dir]=q.times;
ADD(rear);
}
}
printf("%d\n",maxtimes);
return 0;
}