• 开车,开车!!!


    倍增问题

    其实说实话,我现在也不知道倍增问题是什么东西!

    题目链接:
    P1081 开车旅行

    标成如下:

    #include<bits/stdc++.h>
    #define LL long long 
    #define N 100005         //小A开山蹦蹦,小B很正常 0是B 1是A 
    using namespace std;
    struct sd{
        int num,high;
        bool operator < (const sd njc) const
        {
            return high<njc.high;
        }
    }city[N];
    set<sd> s;//定义集合set方便后面排序用。 
    set<sd> ::iterator it;//说白了就是一个指针 
    int goal[N][2],dis[N][2];//分别定义的是N的目标点和N到目标点的距离 
    int loc[N][25], f[N][25][2];//分别存的是 loc从i号点(i<=n)经过2^j的操作到达点的位置(首先存的是一轮)(从goal传入) 
     //f代表从第i个点(i<=N)经过2^j的操作到达点的距离(从dis传入)
    void update(sd x,sd y)
    {
        if(!goal[x.num][0])
        {
            goal[x.num][0]=y.num;
            dis[x.num][0]=abs(x.high-y.high);
        }
        else if(abs(x.high-y.high)<dis[x.num][0]||(abs(x.high-y.high)==dis[x.num][0]&&y.high<city[goal[x.num][0]].high))
        {//如果现在两个的差小于原来的差 或者 相等但是现在的海拔要低一些那么见下面操作 
            goal[x.num][1]=goal[x.num][0];
            dis[x.num][1]=dis[x.num][0];
            goal[x.num][0]=y.num;
            dis[x.num][0]=abs(x.high-y.high);
        }
        else if(abs(x.high-y.high)<dis[x.num][1]||(abs(x.high-y.high)==dis[x.num][1]&&y.high<city[goal[x.num][1]].high))
        {//important
            goal[x.num][1]=y.num;
            dis[x.num][1]=abs(x.high-y.high);
        }
        else if(!goal[x.num][1])
        {
            goal[x.num][1]=y.num;
            dis[x.num][1]=abs(x.high-y.high);
        }
    }
    void query(int i,int x,LL &dista,LL &distb)
    {
        for(int j=20;j>=0;--j)
        {
            if(f[i][j][0]+f[i][j][1]<=x&&loc[i][j])
            {
                dista+=f[i][j][0];
                distb+=f[i][j][1];
                x-=(f[i][j][0]+f[i][j][1]);
                i=loc[i][j];
            }
        }
        if(goal[i][1]&&dis[i][1]<=x)//important 这里的1指的是A,这里在判断最后A是否还可以开车 
        {
            dista+=dis[i][1];
        }
    }
    int main()
    {
        int n;
        cin>>n;//读入
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&city[i].high);
            city[i].num=i;
        } 
        for(int i=n;i>=1;i--)//预处理操作 
        {
            s.insert(city[i]);
            it=s.find(city[i]);
            if(it!=s.begin())
            {
                it--;
                update(city[i],*it);
                if(it!=s.begin())
                {
                    it--;
                    update(city[i],*it);
                    it++;
                }
                it++;
            }
            if((++it)!=s.end())
            {
                update(city[i],*it);
                if((++it)!=s.end())
                    update(city[i],*it);
                    it--;
            }
            it--;
        }
        for(int i=1;i<=n;i++)
        {
            loc[i][0]=goal[goal[i][1]][0];//每一轮开车开完后到达的位置 (A,B算一轮) 
            f[i][0][0]=dis[i][1]; 
            f[i][0][1]=dis[goal[i][1]][0];
        }
        for(int j=1;j<=20;j++)
        {
            for(int i=1;i<=n;i++)
            {
                loc[i][j]=loc[loc[i][j-1]][j-1];
                f[i][j][0]=f[i][j-1][0]+f[loc[i][j-1]][j-1][0];
                f[i][j][1]=f[i][j-1][1]+f[loc[i][j-1]][j-1][1];
            }
        }
        int limit;//下面开始解决题目中的第一个问题!!! 
        cin>>limit;
        LL a=1e5;
        LL b=0;
        int began=0;
        for(int i=1;i<=n;i++)
        {
            LL dista=0, distb=0;
            query(i,limit,dista,distb);
            if(distb&&(distb*a>dista*b))
            {
                began=i;
                a=dista;
                b=distb;
            }
        } 
        //printf("%lld
    ",began)
        cout<<began<<endl;
        int m;
        cin>>m;//下面的代码解决题目中的第二个问题 
        for(int i=1;i<=m;++i)
        {
            LL dista=0,distb=0;
            int s,x;
            scanf("%d%d",&s,&x);
            query(s,x,dista,distb);
            printf("%lld %lld
    ",dista,distb);
            //cout<<dista<<' '<<distb<<endl;
        }
        return 0;
    } 
    

    程序长的我都不想写解题报告了!

    后续持续更新:(2018.2.5 morning)

  • 相关阅读:
    刷题篇--热题HOT 71-80
    刷题篇--热题HOT 61-70
    双飞翼布局介绍-始于淘宝UED
    css布局——百度前端技术学院
    CSS多列布局Multi-column、伸缩布局Flexbox、网格布局Grid详解
    CSS之BFC详解
    深入理解BFC和Margin Collapse
    CSS 布局_如何实现容器中每一行的子容器数量随着浏览器宽度的变化而变化?
    3列、2列自适应布局,中部内容优先显示3列布局等方法
    三列布局,中间自适应
  • 原文地址:https://www.cnblogs.com/mudrobot/p/13330983.html
Copyright © 2020-2023  润新知