HDU - 3533 Escape 【BFS】

本文深入探讨了在ACM竞赛中解决复杂问题的策略,包括人物行动路径规划、子弹发射及碰撞检测等关键算法实现。通过详细的代码示例,讲解了如何在考虑障碍物的情况下,进行高效的人物移动和子弹轨迹计算。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3533

需要注意的点:

1,人不能去有城堡的地方

2,子弹不能穿过城堡,遇到城堡子弹不会继续向前射,即使城堡在途中也不行,比如说子弹从(0, 0) 向 (0, 3)射,如果(0, 1)有城堡,子弹会消失。

3,子弹是从时间 t 开始射击的,不是从0开始。

思路就是人先走,然后遍历每一个城堡的射击时间,如果到了射击时间,就把这个城堡的子弹放入队列里面。然后注意一些限制条件即可。判断子弹是否在射击途中遇到城堡,如果没有就放入队列里面,弹出的子弹记得在那个位置减去一个子弹,表示这个子弹已经离开这个位置了。

#include <iostream>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

const int INF = 0x3f3f3f3f;
const int Maxn = 4e5+10;

struct Shot {
    char dir;
    int i, j, v, t;
} shot[105];

struct Node {
    int i, j, step;
};

int N, M, gun, ener, dir[4][2] = { {1, 0}, {-1, 0},
{0, 1}, {0, -1} }, G[105][105];
bool vis[105][105];

void print() {
    for(int i = 0; i <= N; ++i) {
        for(int j = 0; j <= M; ++j)
            cout << G[i][j] << " ";
        cout << endl;
    }
    cout << endl;
}

void bfs() {
    memset(vis, 0, sizeof(vis));
    queue<Node> quP;
    queue<Shot> quS;
    Node Ntmp; Shot Stmp;
    Ntmp.i = 0; Ntmp.j = 0; Ntmp.step = 0;
    quP.push(Ntmp);
    vis[0][0] = true;

    while (!quP.empty()) {
        int cnt = quP.size(), curtime;
        while (cnt--) {
            Ntmp = quP.front(); quP.pop();
            curtime = Ntmp.step+1;

            if(Ntmp.i == N && Ntmp.j == M) {
                printf("%d\n", Ntmp.step); return;
            }

            for(int i = 0; i < 4; ++i) {
                Node now = Ntmp;
                now.i += dir[i][0]; now.j += dir[i][1];
                if(now.i < 0 || now.i > N || now.j < 0 || now.j > M
                   || vis[now.i][now.j] || G[now.i][now.j] == -1 || G[now.i][now.j] > 0) continue;
                now.step++;
                if(now.step > ener) continue;
                vis[now.i][now.j] = true;
                quP.push(now);
            }
            if(Ntmp.step+1 < ener && G[Ntmp.i][Ntmp.j] == 0) {
                Ntmp.step++; quP.push(Ntmp);
            }
        }

        for(int i = 0; i < gun; ++i)
            if(curtime % shot[i].t == 0) quS.push(shot[i]);

        cnt = quS.size();
        while(cnt--) {
            Stmp = quS.front(); quS.pop();
            if(G[Stmp.i][Stmp.j] > 0)
                G[Stmp.i][Stmp.j]--;

            Shot now = Stmp;
            if(now.dir == 'N' && now.i-now.v >= 0) {
                now.i -= now.v;
                bool ok = true;
                for(int i = Stmp.i-1; i >= now.i; --i) if(G[i][now.j] == -1) ok = false;
                if(ok) {
                    G[now.i][now.j]++;
                    quS.push(now);
                }
            }
            now = Stmp;
            if(now.dir == 'S' && now.i+now.v <= N) {
                now.i += now.v;
                bool ok = true;
                for(int i = Stmp.i+1; i <= now.i; ++i) if(G[i][now.j] == -1) ok = false;
                if(ok) {
                    G[now.i][now.j]++;
                    quS.push(now);
                }
            }
            now = Stmp;
            if(now.dir == 'W' && now.j-now.v >= 0) {
                now.j -= now.v;
                bool ok = true;
                for(int j = Stmp.j-1; j >= now.j; --j) if(G[now.i][j] == -1) ok = false;
                if(ok) {
                    G[now.i][now.j]++;
                    quS.push(now);
                }
            }
            now = Stmp;
            if(now.dir == 'E' && now.j+now.v <= M) {
                now.j += now.v;
                bool ok = true;
                for(int j = Stmp.j+1; j <= now.j; ++j) if(G[now.i][j] == -1) ok = false;
                if(ok) {
                    G[now.i][now.j]++;
                    quS.push(now);
                }
            }
        }
       // print();
    }
    printf("Bad luck!\n");
}

int main(void)
{
    while(scanf("%d%d%d%d", &N, &M, &gun, &ener) != EOF) {
        memset(G, 0, sizeof(G));
        for(int i = 0; i < gun; ++i) {
            scanf(" %c%d%d%d%d", &shot[i].dir,
                  &shot[i].t, &shot[i].v, &shot[i].i, &shot[i].j);
            G[shot[i].i][shot[i].j] = -1;
        }
       // print();
        bfs();
    }
	return 0;
}

 

### 关于HDU - 6609 的题目解析 由于当前未提供具体关于 HDU - 6609 题目的详细描述,以下是基于一般算法竞赛题型可能涉及的内容进行推测和解答。 #### 可能的题目背景 假设该题目属于动态规划类问题(类似于多重背包问题),其核心在于优化资源分配或路径选择。此类问题通常会给出一组物品及其属性(如重量、价值等)以及约束条件(如容量限制)。目标是最优地选取某些物品使得满足特定的目标函数[^2]。 #### 动态转移方程设计 如果此题确实是一个变种的背包问题,则可以采用如下状态定义方法: 设 `dp[i][j]` 表示前 i 种物品,在某种条件下达到 j 值时的最大收益或者最小代价。对于每一种新加入考虑范围内的物体 k ,更新规则可能是这样的形式: ```python for i in range(n): for s in range(V, w[k]-1, -1): dp[s] = max(dp[s], dp[s-w[k]] + v[k]) ``` 这里需要注意边界情况处理以及初始化设置合理值来保证计算准确性。 另外还有一种可能性就是它涉及到组合数学方面知识或者是图论最短路等相关知识点。如果是后者的话那么就需要构建相应的邻接表表示图形结构并通过Dijkstra/Bellman-Ford/Floyd-Warshall等经典算法求解两点间距离等问题了[^4]。 最后按照输出格式要求打印结果字符串"Case #X: Y"[^3]。 #### 示例代码片段 下面展示了一个简单的伪代码框架用于解决上述提到类型的DP问题: ```python def solve(): t=int(input()) res=[] cas=1 while(t>0): n,k=list(map(int,input().split())) # Initialize your data structures here ans=find_min_unhappiness() # Implement function find_min_unhappiness() res.append(f'Case #{cas}: {round(ans)}') cas+=1 t-=1 print("\n".join(res)) solve() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值