hdu1242 Rescue 优先队列BFS

Angel's friends want to save Angel. Their task is: approach Angel. We assume that "approach Angel" is to get to the position where Angel stays. When there's a guard in the grid, we must kill him (or her?) to move into the grid. We assume that we moving up, down, right, left takes us 1 unit time, and killing a guard takes 1 unit time, too. And we are strong enough to kill all the guards.

题解:某某被困在一个地方,他朋友要去解救他(朋友不止一个)。在杀死守卫增加一秒的条件下求出最短的时间救出他。

定义结构体是必要的,保存每步的时间并且更新,使用优先队列,优先队列的判断条件是结构体里面的友元函数:按照最少的时间(tmp)来排列。然后BFS搜索之。

#include<cstdlib>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<queue>
#include<algorithm>
#define LL long long
#define maxn 1001
#define INF 2147483646
using namespace std;
#define eps 1e-7
#define pi acos(-1.0)
int n,m,sx,sy,ans;
char a[maxn][maxn];
int vit[maxn][maxn];
int f[4][2]={0,1,1,0,0,-1,-1,0};
struct node {
    int x;
    int y;
    int tmp;
    friend bool operator < (const node &s,const node &b)//友元函数,优先队列的判定条件
    {
        return s.tmp>b.tmp;
    }
};
int bfs(int x,int y)
{
    priority_queue<node>Q;
    node s,q;
    memset(vit,0,sizeof(vit));
    s.x=x;
    s.y=y;
    s.tmp=0;
    vit[s.x][s.y]=1;
    Q.push(s);
    while(!Q.empty())
    {
        s=Q.top();
        Q.pop();
        if(a[s.x][s.y]=='r')
            return s.tmp;
        for(int i=0;i<4;i++)
        {
            q.x=s.x+f[i][0];
            q.y=s.y+f[i][1];
            if(q.x>=1&&q.x<=n&&q.y>=1&&q.y<=m&&a[q.x][q.y]!='#'&&!vit[q.x][q.y])
            {
                vit[q.x][q.y]=1;
                if(a[q.x][q.y]=='x')
                    q.tmp=s.tmp+2;
                else
                    q.tmp=s.tmp+1;
                Q.push(q);
            }
        }
    }
    return 0;
}
int main()
{
    while(cin>>n>>m)
    {
        ans=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
            if(a[i][j]=='a')
                sx=i,sy=j;
        }
        ans=bfs(sx,sy);
        if(ans>0)
            cout<<ans<<endl;
        else
            cout<<"Poor ANGEL has to stay in the prison all his life."<<endl;
    }
}


对于HDU4546问题,还可以使用优先队列(Priority Queue)来解决。以下是使用优先队列的解法思路: 1. 首先,将数组a进行排序,以便后续处理。 2. 创建一个优先队列(最小堆),用于存储组合之和的候选值。 3. 初始化优先队列,将初始情况(即前0个数的组合之和)加入队列。 4. 开始从1到n遍历数组a的元素,对于每个元素a[i],将当前队列中的所有候选值取出,分别加上a[i],然后再将加和的结果作为新的候选值加入队列。 5. 重复步骤4直到遍历完所有元素。 6. 当队列的大小超过k时,将队列中的最小值弹出。 7. 最后,队列中的所有候选值之和即为前k小的组合之和。 以下是使用优先队列解决HDU4546问题的代码示例: ```cpp #include <iostream> #include <vector> #include <queue> #include <functional> using namespace std; int main() { int n, k; cin >> n >> k; vector<int> a(n); for (int i = 0; i < n; i++) { cin >> a[i]; } sort(a.begin(), a.end()); // 对数组a进行排序 priority_queue<long long, vector<long long>, greater<long long>> pq; // 最小堆 pq.push(0); // 初始情况,前0个数的组合之和为0 for (int i = 0; i < n; i++) { long long num = pq.top(); // 取出当前队列中的最小值 pq.pop(); for (int j = i + 1; j <= n; j++) { pq.push(num + a[i]); // 将所有加和结果作为新的候选值加入队列 num += a[i]; } if (pq.size() > k) { pq.pop(); // 当队列大小超过k时,弹出最小值 } } long long sum = 0; while (!pq.empty()) { sum += pq.top(); // 求队列中所有候选值之和 pq.pop(); } cout << sum << endl; return 0; } ``` 使用优先队列的方法可以有效地找到前k小的组合之和,时间复杂度为O(nklog(k))。希望这个解法对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值