求助E题反复横跳和F题图题目的思路,E题已会,求助F题大佬

求助,E题反复横跳的思路,是动态规划吗?还有F题的思路。。。
E题我用下面这个BFS结果内存爆了。。。
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
struct node{
    int pos,op,step;
    node(int pos,int op,int step):pos(pos),op(op),step(step){}
};
int main() {
    int s,t;
    cin>>s>>t;
    if(s == t){
        cout<<"0"<<endl;
        return 0;
    }
    int op = 1,step = 1;
    vector<int> v;
    int sum = 0;
    queue<node>q1,q2;
    q1.push(node(s,1,1));
    int res = 0;
    while(!q1.empty()){
        res++;
        while(!q1.empty()){
            node n1 = q1.front();
            if(n1.pos == t){
                cout<<res-1<<endl;
                return 0;
            }
            q1.pop();
            q2.push(node(n1.pos+n1.op*n1.step,n1.op*-1,n1.step*2));
            q2.push(node(n1.pos,1,1));
        }
        swap(q1,q2);
    }
    return 0;
}

好吧,我终于写出来了。。果然还是BFS,用的是楼下某位大佬提供的思路,用最短路径算法就可,初步体验了下优先队列。。太强了。。
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
struct node{
    int dis;
    int pos;
    node(int dis,int pos):dis(dis),pos(pos){}
    bool operator <(const node& tmp)const{
        return dis>tmp.dis;
    }
};
int main() {
    int s,t,step = 1,sum = 0;
    cin>>s>>t;
    vector<int> v;
    //前17个数:0 1 -1 3 -5 11 -21 43 -85 171 -341 683 -1365 2731 -5461 10923 -21845
    for(int i = 0;i<17;i++){
        v.push_back(sum);
        sum+= step;
        step *= -2;
    }
    //为了保证dis数组的下标为正数,s,t都加25000;
    s+=25000;t+=25000;
    vector<int>dist(60000,INT32_MAX);
    vector<int>vis(60000,0);
    priority_queue<node> pq;   //默认大顶堆,所以结构体重载大于号
    pq.push(node(0,s));
    while(!pq.empty()){
        node node1 = pq.top();  //醉了,队列queue是front,优先队列是top()
        pq.pop();
        if(node1.dis>dist[node1.pos])
            continue;
        if(node1.pos == t){
            cout<<node1.dis;
            break;
        }
        //对于每个节点加入在该节点重置,后继续跳17步之内的所有节点
        //至于该节点继续再本身step基础上再*2跳的节点不考虑,因为之前已经考虑过了,
        //那么也就意味着结构体中不需要保存当前节点的step和op!太妙了,哈哈
        for(int i = 1;i<17;i++){
            int pos = node1.pos+v[i],cost = node1.dis+i+1;
            if(pos<0 || pos>50000)    break;     //防止dist下标越界
            if(vis[pos])    continue;            //不加这个会超时,太难了。。
            if(node1.dis == 0) cost--;           //如果是第一个从S出发的节点,需要减1
            pq.push(node(cost,pos));
            dist[pos] = min(dist[pos],cost);
            vis[pos] = 1;
        }
    }
    return 0;
}



全部评论
E题我用贪心解决了 把横跳看作可以选择的移动距离,例如一次横跳为1, 二次横跳为1 - 2 = -1, 三次横跳为1 - 2 + 4 = 3,依次类推; 最终能选的有20个,因为20次横跳已经30+万了 那么问题就变成了,如何在20个数中,选出几个数,使得和等于t - s且步骤最少。 用贪心策略,每次选择一个局部最优的移动距离即可。
3 回复
分享
发布于 2021-04-24 19:39
在线等E题的代码
点赞 回复
分享
发布于 2021-04-24 17:30
博乐游戏
校招火热招聘中
官网直投
E题BFS,F题统计每条边贡献
点赞 回复
分享
发布于 2021-04-24 17:31
可以用迪杰斯特拉算法解,+-20000范围内每个整数都是点,从一个数重置一次+跳n次可以到达另一个数就是有边,n+1就是边长。
点赞 回复
分享
发布于 2021-04-24 21:37
E题终于解决了。。哪位大佬会F题。。
点赞 回复
分享
发布于 2021-04-25 13:27
我思路和楼主一致,但是就是两处细节不一样: 1、请问43行 cost = node1.dis+i+1 这里为什么要+1呀? 2、还有就是46行这里,为什么要cost--呀 求大神解释一下谢谢!
点赞 回复
分享
发布于 2021-04-26 09:23

相关推荐

点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务