[USACO07OCT] 障碍路线Obstacle Course

移步到新Blog获得更好的代码阅读体验










搬过我在洛谷的题解

目前最快的BFS算法

先来说一下思路吧,鄙人不才,表达能力有很大欠缺,如果理解有误,那完全是我的错。

这道题可以用一个特殊的BFS来求解。每次把队首元素四个方向上的点扩展到队尾,用桶来记录转弯次数。

1.初始状态

A(起点)的转弯次数为-1。

2.产生结点的规则

现在,起点位于队首。

从队首的点向四周逐“层”扩展,每一“层”扩展到的新点入队列,这些新点显然不需要转弯就可以达到(起点任意方向),所以他们的转弯次数记录为0 (也就是起点+1,你的疑问马上就会得到解答)

[USACO07OCT] 障碍路线Obstacle Course_第1张图片

这就是产生新结点的策略。

3.记录每个点的转弯次数

扩展到的新点的转弯次数=队首点的转弯次数+1。(由于BFS的特点,新点未被访问过才可以被加入队尾)

下面是证明。

如果扩展到的新点是不转90°(直走)就可以到的,那该点一定被扩展了队首点的点(队首点的父结点,不知道这么说对不对)访问过,此时该点不会被当作新点处理。同理,转弯180°的点也一定被扩展了队首点的点访问过。

所以,扩展到的新点一定是转弯90°(左或右)才能走到的。

此时,到新点的转弯次数=队首点的转弯次数+1。

证明完毕。

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

int n;//地图大小 
int timex[200][200]={0};//转弯次数记录 
int cachex,cachey,sx,sy,ex,ey;//起点,终点坐标和队首坐标缓存 
int wayx[4]={-1,0,1,0},wayy[4]={0,1,0,-1};//方向表 
queuequex,quey;
char mapx[200][200]={0};//地图 
bool teller[4]={true};//扩展层数判断 

void showTimex()//输出到地图各点的转弯次数 
{
    cout<>mapx[i][j];
        if (mapx[i][j]=='A'){sx=i;sy=j;}//记录起点 
        if (mapx[i][j]=='B'){ex=i;ey=j;mapx[i][j]='.';}//记录终点并且让终点可以入队 
    }
    //cout<0)
    {
        memset(teller,true,sizeof(teller));//初始化 扩展层数判断变量 
        cachex=quex.front(); cachey=quey.front();//缓存存入 
        if (cachex==ex && cachey==ey)//如果到了终点,输出(这个题不存在起点=终点的情况,因为分别用AB表示 
        {
            cout<=0 && cachex+wayx[j]*i=0 && cachey+wayy[j]*i



你可能感兴趣的:([USACO07OCT] 障碍路线Obstacle Course)