【BZOJ1616】[Usaco2008 Mar]Cow Travelling 游荡的奶牛

描述 Description

奶牛们在被划分成 N 行 M 列 (2 <= N <= 100; 2 <= M <= 100) 的草地上游走,试图找到整块草地中最美味的牧草。Farmer John 在某个时刻看见贝茜在位置 (R1, C1),恰好 T (0 < T <= 15)秒后,FJ 又在位置 (R2, C2) 与贝茜撞了正着。 FJ 并不知道在这 T 秒内贝茜是否曾经到过 (R2, C2),他能确定的只是,现在贝茜在那里。 设 S 为奶牛在 T 秒内从(R1, C1) 走到 (R2, C2) 所能选择的路径总数,FJ 希望有一个程序来帮他计算这个值。每一秒内,奶牛会水平或垂直地移动 1 单位距离(奶牛总是在移动,不会在某秒内停在它上一秒所在的点)。草地上的某些地方有树,自然,奶牛不能走到树所在的位置,也不会走出草地。 现在你拿到了一张整块草地的地形图,其中’.‘表示平坦的草地,’*’表示挡路的树。你的任务是计算出,一头在 T 秒内从 (R1, C1) 移动到 (R2, C2) 的奶牛可能经过的路径有哪些。

输入格式 InputFormat

第 1 行: 3 个用空格隔开的整数:N,M,T.

第 2..N+1 行: 第 i+1 行为 M 个连续的字符,描述了草地第 i 行各点的情况,保证 字符是’.‘和’’中的一个 第 N+2 行: 4 个用空格隔开的整数:R1,C1,R2,以及 C2.

输出格式 OutputFormat

第 1 行: 输出 S,含义如题中所述

样例输入 SampleInput

10 10 7
……..
..
……
………
.
.…..
……….
...….
……….
.
..
….**
……..
…***….
5 4 7 3

样例输出 SampleOutput

74

数据范围和注释 Hint

草地被划分成 4 行 5 列,奶牛在 6 秒内从第 1 行第 3 列走到了第 1 行第 5 列。

奶牛在 6 秒内从 (1,3) 走到 (1,5) 的方法只有一种(绕过她面前的树)。

来源 Source

Silver


BZOJ 1616


代码 Code

记忆化搜索。

#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
struct point
{
    int z,y,x;
}f[1000000];
int dx[5]={0,0,0,1,-1};
int dy[5]={0,1,-1,0,0};
char a[101][101];
int c[101][101][16];
bool b[101][101][16];
int i,j,t,n,m,l,r,k,z,y,x,sx,sy,ex,ey,ans;
void TEST()
{
    int i,j,t;
    for (i=1;i<=n;i++)
    {
        for (j=1;j<=m;j++) cout<<a[i][j];
        cout<<endl;
    }
    cout<<endl;
}
int main()
{
    scanf("%d%d%dn",&n,&m,&t);
    for (i=1;i<=n;i++) scanf("%s",a[i]+1);
    scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
    memset(c,0,sizeof(c));
    memset(b,false,sizeof(b));
    l=0;r=l;f[l].x=sx;f[l].y=sy;f[l].z=0;
    c[f[l].x][f[l].y][f[l].z]=1;
    b[f[l].x][f[l].y][f[l].z]=true;
    while (r>=l)
    {
        if (f[l].z>t) break;
        for (i=1;i<=4;i++)
        {
            int tx=f[l].x+dx[i];
            int ty=f[l].y+dy[i];
            if (tx<=0 || ty<=0 || tx>n || ty>m || a[tx][ty]=='*') continue;
            c[tx][ty][f[l].z+1]+=c[f[l].x][f[l].y][f[l].z];
            if (!b[tx][ty][f[l].z+1])
            {
                b[tx][ty][f[l].z+1]=true;
                f[++r].x=tx;f[r].y=ty;f[r].z=f[l].z+1;
            }
        }
        l++;
    }
    printf("%d\n",c[ex][ey][t]);
    return 0;
}