BZOJ 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课

Description

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

. . B x .
. x x A .
. . . x .
. x . . .
. . x . .

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

Input

第 1行: 一个整数 N 行

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

Output

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

Sample Input

3
.xA
...
Bx.

Sample Output

2

 

题解

bfs。感觉我还是很弱,刚开始脑子一团浆糊。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cmath>
#define inf 1<<30
using namespace std;
int n,xs,ys,yt,xt,map[105][105];
int f[105][105][4];
struct dui{int x,y,d,step;} q[40005];
int xx[4]={-1,1,0,0},yy[4]={0,0,-1,1};
void init()
{
	scanf("%d",&n);
	int i,j;
	char ch[105];
	for(i=1;i<=n;i++)
	   {scanf("%s",ch);
	    for(j=0;j<n;j++)
	       {if(ch[j]=='x') map[i][j+1]=-1;
	        else
			   {if(ch[j]=='A') {xs=i; ys=j+1;}
			    else if(ch[j]=='B') {xt=i; yt=j+1;}
			   }
		   }
	   }
}
void dfs()
{
	int i,t=0,w=0,xn,yn,dn,sn,xto,yto;
	for(i=0;i<4;i++)
	   {q[w].x=xs; q[w].y=ys; q[w].d=i; q[w].step=0;
	    f[xs][ys][i]=0;
		w=(w+1)%40001; 
	   }
	while(t!=w)
	   {xn=q[t].x; yn=q[t].y; dn=q[t].d; sn=q[t].step;
	    t=(t+1)%40001;
		for(i=0;i<4;i++)
	       {if(sn+1<f[xn][yn][i])
		       {q[w].x=xn; q[w].y=yn; q[w].d=i; q[w].step=sn+1;
			    f[xn][yn][i]=sn+1;
			    w=(w+1)%40001;
			   }
		   }
		xto=xn+xx[dn]; yto=yn+yy[dn];
		if(xto<1||yto<1||xto>n||yto>n||map[xto][yto]==-1) continue;
		if(f[xn][yn][dn]<f[xto][yto][dn])
		   {q[w].x=xto; q[w].y=yto; q[w].d=dn; q[w].step=f[xn][yn][dn];
		    f[xto][yto][dn]=f[xn][yn][dn];
		    w=(w+1)%40001;
		   }
	   }
}
int main()
{
	init();
	memset(f,127/3,sizeof(f));
	dfs();
	int ans=inf;
	for(int i=0;i<4;i++)
		ans=min(ans,f[xt][yt][i]);
	printf("%d",ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值