zoukankan      html  css  js  c++  java
  • 开车,开车!!!

    倍增问题

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

    题目链接:
    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)

  • 相关阅读:
    JDBC 查询的三大参数 setFetchSize prepareStatement(String sql, int resultSetType, int resultSetConcur)
    有空必看
    SpringMVC 利用AbstractRoutingDataSource实现动态数据源切换
    FusionCharts JavaScript API Column 3D Chart
    FusionCharts JavaScript API
    FusionCharts JavaScript API
    Extjs 继承Ext.Component自定义组件
    eclipse 彻底修改复制后的项目名称
    spring 转换器和格式化
    Eclipse快速生成一个JavaBean类的方法
  • 原文地址:https://www.cnblogs.com/mudrobot/p/13330983.html
Copyright © 2011-2022 走看看