您的位置:首页 > 其它

ACM 161. [USACO Oct07] 障碍训练场(计数BFS)

2014-08-30 09:48 525 查看


161. [USACO Oct07] 障碍训练场

★☆ 输入文件:
obstacle.in
输出文件:
obstacle.out
简单对比

时间限制:1 s 内存限制:128 MB

译 By CmYkRgB123
考虑一个 N x N (1 <= N <= 100)的有1个个方格组成的正方形牧场。有些方格是奶牛们不能踏上的,它们被标记为了'x'。例如下图:
. . B x .
. x x A .
. . . x .
. x . . .
. . x . .

贝茜发现自己恰好在点A出,她想去B处的盐块添盐。缓慢而且笨拙的动物,比如奶牛,十分讨厌转弯。尽管如此,当然在必要的时候她们还是会转弯的。对于一个给定的牧场,请你计算从A到B最少的转弯次数。开始的时候,贝茜可以使面对任意一个方向。贝茜知道她一定可以到达。
程序名: obstacle
输入

行 1: 一个整数 N
行 2..N + 1: 行 i+1 有 N 个字符 ('.', 'x', 'A', 'B'),表示每个点的状态。

输出

行 1: 一个整数,最少的转弯次数。

输入样例
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: