HDU 3085 双广

n*m地图上有

‘. ’:路

‘X':墙

’Z':鬼,每秒蔓延2个单位长度,能够穿墙。共两个,每秒開始时鬼先动

‘M’:一号,每分钟可移动3个单位长度

‘G’:二号,每分钟课移动1个单位长度

问两人能否够成功碰面,再不被鬼吃掉的前提下


双向广搜。对于‘M’。每次搜三步,对于‘G’,每次搜一步。和鬼的距离可用曼哈顿距离计算推断

注意每秒開始时鬼先移动


#include "stdio.h"
#include "string.h"
#include "algorithm"
#include "queue"
using namespace std;

const int dir[4][2]={ {1,0},{-1,0},{0,1},{0,-1} };
char str[810][810];
int used[2][810][810];
int g_x,g_y,m_x,m_y,n,m,step;

struct node
{
    int x,y;
}ncur,z[2];

queue<node>q[2];

void init()
{
    int i,j,cnt;
    scanf("%d%d",&n,&m);
    for (i=0;i<n;i++)
        scanf("%s",str[i]);
    cnt=0;
    for (i=0;i<n;i++)
        for (j=0;j<m;j++)
        {
            if (str[i][j]=='G')
            {
                g_x=i; g_y=j;
            }
            if (str[i][j]=='M')
            {
                m_x=i; m_y=j;
            }
            if (str[i][j]=='Z')
            {
                z[cnt].x=i;
                z[cnt++].y=j;
            }
        }
}

int judge(node b)
{
    if (b.x<0 || b.y<0 || b.x>=n || b.y>=m) return 0;
    if (str[b.x][b.y]=='X') return 0;
    if ((abs(b.x-z[0].x)+abs(b.y-z[0].y))<=2*step) return 0;
    if ((abs(b.x-z[1].x)+abs(b.y-z[1].y))<=2*step) return 0;
    return 1;
}

int bfs(int w)
{
    node cur,next;
    int i,sum;

    sum=q[w].size();
    while (sum--)
    {
        cur=q[w].front();
        q[w].pop();
        if (judge(cur)==0) continue;
        for (i=0;i<4;i++)
        {
            next.x=cur.x+dir[i][0];
            next.y=cur.y+dir[i][1];
            if (judge(next)==0) continue;
            if (used[w][next.x][next.y]==0)
            {
                if (used[w^1][next.x][next.y]==1) return 1;
                used[w][next.x][next.y]=1;
                q[w].push(next);
            }
        }
    }
    return 0;
}
int solve()
{
    while (!q[0].empty()) q[0].pop();
    while (!q[1].empty()) q[1].pop();

    ncur.x=m_x;
    ncur.y=m_y;
    q[0].push(ncur);
    ncur.x=g_x;
    ncur.y=g_y;
    q[1].push(ncur);
    memset(used,0,sizeof(used));
    used[0][m_x][m_y]=used[1][g_x][g_y]=1;
    step=0;

    while ((!q[0].empty()) || (!q[1].empty()))
    {
        step++;
        if (bfs(0)==1) return step;
        if (bfs(0)==1) return step;
        if (bfs(0)==1) return step;
        if (bfs(1)==1) return step;
    }
    return -1;

}
int main()
{
    int Case;
    scanf("%d",&Case);
    while (Case--)
    {
        init();
        printf("%d\n",solve());
    }
    return 0;
}



内容概要:本文档主要展示了C语言中关于字符串处理、指针操作以及动态内存分配的相关代码示例。首先介绍了如何实现键值对(“key=value”)字符串的解析,包括去除多余空格和根据键获取对应值的功能,并提供了相应的测试用例。接着演示了从给定字符串中分离出奇偶位置字符的方法,并将结果分别存储到两个不同的缓冲区中。此外,还探讨了常量(const)修饰符在变量和指针中的应用规则,解释了不同类型指针的区别及其使用场景。最后,详细讲解了如何动态分配二维字符数组,并实现了对这类数组的排序与释放操作。 适合人群:具有C语言基础的程序员或计算机科学相关专业的学生,尤其是那些希望深入理解字符串处理、指针操作以及动态内存管理机制的学习者。 使用场景及目标:①掌握如何高效地解析键值对字符串并去除其中的空白字符;②学会编写能够正确处理奇偶索引字符的函数;③理解const修饰符的作用范围及其对程序逻辑的影响;④熟悉动态分配二维字符数组的技术,并能对其进行有效的排序和清理。 阅读建议:由于本资源涉及较多底层概念和技术细节,建议读者先复习C语言基础知识,特别是指针和内存管理部分。在学习过程中,可以尝试动手编写类似的代码片段,以便更好地理解和掌握文中所介绍的各种技巧。同时,注意观察代码注释,它们对于理解复杂逻辑非常有帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值