当前位置: 首页 > news >正文

开车,开车!!!

倍增问题

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

题目链接:
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)){//importantgoal[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\n",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\n",dista,distb);//cout<<dista<<' '<<distb<<endl;}return 0;
} 

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

后续持续更新:(2018.2.5 morning)


http://www.taodudu.cc/news/show-6310412.html

相关文章:

  • 【physx/wasm】在physx中添加自定义接口并重新编译wasm
  • excel---常用操作
  • Lora训练Windows[笔记]
  • linux基础指令讲解(ls、pwd、cd、touch、mkdir)
  • InnoDB 事务处理机制
  • 启明云端ESP32 C3 模组WT32C3通过 MQTT 连接 AWS
  • 你为什么喜欢开车?
  • dmesg介绍
  • Linux--常用命令--dmesg
  • dmesg命令手册
  • dmesg 命令详解
  • linux dmesg命令参数及用法详解
  • linux命令之-dmesg详解
  • dmesg命令用法
  • Linux 系统设置 : dmesg 命令详解
  • dmesg七种用法
  • Linux命令:dmesg
  • dmesg的详细用法
  • linux命令--dmesg
  • 图解Linux命令之--dmesg命令
  • 2023年JAVA JDK8的安装与配置(附JAVA8安装包)
  • java-jdk下载及安装
  • Java软件包安装
  • java程序打包一体化:代码-jar-exe-安装包(图文详解、资源提供)
  • 把java项目打包成安装包,在windows下安装
  • java中jdk的下载与安装
  • 把java项目打包成安装包
  • java安装教程(解决官网下载的安装包为什么没有jre?)
  • 阿里云ACP ACE认证考试重要事项
  • 树莓派呼吸灯python代码
  • pyboard呼吸灯代码分享
  • esp32 + python 呼吸灯实现
  • Python| GUI界面进行抽奖
  • 1.python网页设计,点击按键显示对话窗口
  • 【python】简单使用selenium编写无界面谷歌浏览器的网页登录和签到功能
  • Python3.x+Pyqt5实现界面编程浏览网页