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

本文介绍了如何运用计数BFS算法解决USACO竞赛中2007年10月的障碍训练场问题。通过BFS策略,详细探讨了如何在遇到障碍时有效地计算路径数量。
摘要由CSDN通过智能技术生成

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值