【题解】开车旅行

开车旅行
(drive.cpp/c/pas)
【问题描述】
小A 和小B决定利用假期外出旅行,他们将想去的城市从1到N 编号,且编号较小的
城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i的海拔高度为
Hi,城市 i 和城市 j 之间的距离 d[i,j]恰好是这两个城市海拔高度之差的绝对值,即
d[i, j] = |???? − ????|。
旅行过程中,小A 和小B轮流开车,第一天小A 开车,之后每天轮换一次。他们计划
选择一个城市 S 作为起点,一直向东行驶,并且最多行驶 X 公里就结束旅行。小 A 和小B
的驾驶风格不同,小 B 总是沿着前进方向选择一个最近的城市作为目的地,而小 A 总是沿
着前进方向选择第二近的城市作为目的地(注意:本题中如果当前城市到两个城市的距离
相同,则认为离海拔低的那个城市更近)。如果其中任何一人无法按照自己的原则选择目的
城市,或者到达目的地会使行驶的总距离超出X公里,他们就会结束旅行。
在启程之前,小A 想知道两个问题:
1.对于一个给定的 X=X0,从哪一个城市出发,小 A 开车行驶的路程总数与小 B 行驶
的路程总数的比值最小(如果小 B的行驶路程为0,此时的比值可视为无穷大,且两个无穷大视为相等) 。

如果从多个城市出发,小A 开车行驶的路程总数与小B行驶的路程总数的比
值都最小,则输出海拔最高的那个城市。
2.  对任意给定的 X=Xi和出发城市 Si,小 A 开车行驶的路程总数以及小 B 行驶的路程
总数。
 
【输入】
输入文件为drive.in。
第一行包含一个整数 N,表示城市的数目。
第二行有 N 个整数,每两个整数之间用一个空格隔开,依次表示城市 1 到城市 N 的海
拔高度,即H1,H2,……,Hn,且每个Hi都是不同的。
第三行包含一个整数 X0。
第四行为一个整数 M,表示给定M组Si和 Xi。
接下来的M行,每行包含2个整数Si和Xi,表示从城市 Si出发,最多行驶Xi公里。
 
【输出】

输出文件为drive.out。
输出共M+1 行。
第一行包含一个整数S0,表示对于给定的X0,从编号为S0的城市出发,小A开车行驶
的路程总数与小B行驶的路程总数的比值最小。
接下来的 M 行,每行包含 2 个整数,之间用一个空格隔开,依次表示在给定的 Si和
Xi下小A行驶的里程总数和小B 行驶的里程总数。
 
【输入输出样例1】
drive.in   drive.out
4
2 3 1 4    1
3       1 1
4       2 0
1 3     0 0
2 3     0 0
3 3
4 3

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <fstream>
  4 #include <cstdlib>
  5 #include <string>
  6 #include <cmath>
  7 using namespace std;
  8 /* run this program using the console pauser or add your own getch, system("pause") or input loop */
  9
 10 ifstream fin("drive.in");
 11 ofstream fout("drive.out");
 12
 13 int cities=0;
 14 int x0=0;
 15 //bool pd=false;
 16 int dao[100002][2]={0};
 17 int gao[100000]={0};
 18 struct id{
 19     int nxt;
 20     long long int cnt_a;
 21     long long int cnt_b;
 22 };
 23     id jiyi[100002]={0};
 24
 25 void yuchu(int s1ze);
 26 void yuchu2(int s1ze);
 27 void cha(int xu,int zong);
 28 void bijiao(int zi,int mu);
 29 void bi(int zi,int mu);
 30 void cha2(int xu,int zong);
 31
 32
 33 int zmin=0,cmin=0;
 34 void yuchu(int s1ze){
 35      zmin=2000000002;cmin=2000000002;
 36      for(int x=s1ze+1;x<=cities;x++){
 37          long long jian=abs(gao[s1ze]-gao[x]);
 38          int hao=dao[s1ze][1];
 39          if(jian<cmin){
 40             cmin=jian;
 41             dao[s1ze][1]=x;
 42             if(jian<zmin){
 43               int a=zmin;
 44               zmin=jian;cmin=a;
 45               int b=dao[s1ze][1];
 46               dao[s1ze][1]=dao[s1ze][0];
 47               dao[s1ze][0]=b;
 48             }
 49             else if(jian==zmin){
 50               int hao1=dao[s1ze][0];
 51               //cout<<hao<<" "<<x<<endl;
 52               if(gao[hao1]>gao[x]){
 53                int a=zmin;
 54                zmin=jian;cmin=a;
 55                int b=dao[s1ze][1];
 56                dao[s1ze][1]=dao[s1ze][0];
 57                dao[s1ze][0]=b;
 58               }
 59             }
 60          }
 61
 62          else if(jian==cmin&&gao[hao]>gao[x]){
 63            cmin=jian;
 64            dao[s1ze][1]=x;
 65            hao=dao[s1ze][0];
 66            if(jian==zmin&&gao[hao]>gao[x]){
 67                int a=zmin;
 68             zmin=jian;cmin=a;
 69             int b=dao[s1ze][1];
 70             dao[s1ze][1]=dao[s1ze][0];
 71             dao[s1ze][0]=b;
 72            }
 73          }
 74      }
 75      return;
 76 }
 77
 78 void yuchu2(int s1ze){
 79      int hao=dao[s1ze][1];
 80      if(hao==0)return;
 81      jiyi[s1ze].cnt_a=abs(gao[s1ze]-gao[hao]);
 82      int hao2=dao[hao][0];
 83      if(hao2==0)return;
 84      jiyi[s1ze].cnt_b=abs(gao[hao]-gao[hao2]);
 85      jiyi[s1ze].nxt=hao2;
 86      yuchu2(hao2);
 87      jiyi[s1ze].cnt_a+=jiyi[hao2].cnt_a;
 88      jiyi[s1ze].cnt_b+=jiyi[hao2].cnt_b;
 89 }
 90
 91 //int zi=0,mu=0,ans[2]={0};
 92 void cha(int xu,int zong){
 93      long long int zo_a=jiyi[xu].cnt_a;
 94      long long int zo_b=jiyi[xu].cnt_b;
 95      //cout<<zo_a<<" "<<zo_b<<endl;
 96      int erfen[100002]={0};
 97      int cnt=0,zhi=xu;
 98      erfen[0]=xu;
 99      while(jiyi[zhi].nxt!=0){
100          erfen[++cnt]=jiyi[zhi].nxt;
101          zhi=jiyi[zhi].nxt;
102      }
103
104      long long int he=zo_b+zo_a;
105      if(he<=zong){
106        bijiao(zo_a,zo_b);
107        return;
108      }
109
110      int ks=1,js=cnt;
111      long long a_z=0,b_z=0,luch1=0;
112
113      while(ks<=js){
114          int mid=(ks+js)/2;
115          int hao=erfen[mid];
116          long long int luch=(zo_a-jiyi[hao].cnt_a)+(zo_b-jiyi[hao].cnt_b);
117          if(luch<zong){
118               if(luch>luch1){
119                a_z=zo_a-jiyi[hao].cnt_a;
120               b_z=zo_b-jiyi[hao].cnt_b;
121                ks=mid+1;
122                luch1=luch;
123               }
124          }
125
126          else if(luch>zong){
127               int hao2=erfen[mid-1];
128              int luchc=(zo_a-jiyi[hao].cnt_a)+(zo_b-jiyi[hao2].cnt_b);
129               if(luchc<=zong){
130                 a_z=zo_a-jiyi[hao].cnt_a;
131                b_z=zo_b-jiyi[hao2].cnt_b;
132                break;
133               }
134               else js=mid-1;
135          }
136          else if(luch==zong){
137               a_z=zo_a-jiyi[hao].cnt_a;
138              b_z=zo_b-jiyi[hao].cnt_b;
139               break;
140          }
141      }
142      //cout<<a_z<<" "<<b_z<<endl;
143      bijiao(a_z,b_z);
144      return;
145 }
146
147 int zgao=0,bgao=0,sze_city=0,b_city=0;
148 long long zzi,zmu;
149 void bijiao(int zi,int mu){
150      if(zmu==0&&zzi==0){
151           sze_city=b_city;
152          zgao=bgao;
153          zzi=zi;
154          zmu=mu;
155          return;
156      }
157      else if(mu==0&&zmu==0){
158          bi(zi,mu);
159      }
160      double zhi1=0,zhi2=0;
161      zhi1=(double)zzi/zmu;
162      zhi2=(double)zi/mu;
163      if(zhi1>zhi2){
164          zzi=zi;zmu=mu;
165          sze_city=b_city;
166          zgao=bgao;
167      }
168      if(zhi1==zhi2){
169          bi(zi,mu);
170      }
171      return;
172 }
173
174 void bi(int zi,int mu){
175      long long zi1=0,zi2=0;
176      zi1=zzi*mu;
177      zi2=zi*zmu;
178      if(zi1>zi2){
179          zzi=zi;zmu=mu;
180          sze_city=b_city;
181          zgao=bgao;
182      }
183      if(zi1==zi2){
184          if(zgao<bgao){
185             zzi=zi;zmu=mu;
186             sze_city=b_city;
187             zgao=bgao;
188          }
189      }
190      return;
191 }
192
193 long long int ans_a=0,ans_b=0;
194 void cha2(int xu,int zong){
195      long long int zo_a=jiyi[xu].cnt_a;
196      long long int zo_b=jiyi[xu].cnt_b;
197
198      int erfen[100002]={0};
199      int cnt=0,zhi=xu;
200      erfen[0]=xu;
201      while(jiyi[zhi].nxt!=0){
202          erfen[++cnt]=jiyi[zhi].nxt;
203          if(xu==3){
204              cout<<erfen[cnt]<<" "<<endl;
205          }
206          zhi=jiyi[zhi].nxt;
207      }
208      cout<<endl;
209      long long int he=zo_b+zo_a,luch1=0;
210      if(he<=zong){
211        ans_a=zo_a;
212        ans_b=zo_b;
213        return;
214      }
215
216
217      int ks=1,js=cnt;
218      while(ks<=js){
219          int mid=(ks+js)/2;
220          int hao=erfen[mid];
221          long long int luch=(zo_a-jiyi[hao].cnt_a)+(zo_b-jiyi[hao].cnt_b);
222          if(luch<zong&&luch>luch1){
223               ans_a=zo_a-jiyi[hao].cnt_a;
224              ans_b=zo_b-jiyi[hao].cnt_b;
225               ks=mid+1;
226               luch1=luch;
227          }
228
229          else if(luch>zong){
230               int hao2=erfen[mid-1];
231              int luchc=(zo_a-jiyi[hao].cnt_a)+(zo_b-jiyi[hao2].cnt_b);
232               if(luchc<=zong){
233                 ans_a=zo_a-jiyi[hao].cnt_a;
234                ans_b=zo_b-jiyi[hao2].cnt_b;
235                break;
236               }
237               else js=mid-1;
238          }
239          else if(luch==zong){
240               ans_a=zo_a-jiyi[hao].cnt_a;
241              ans_b=zo_b-jiyi[hao].cnt_b;
242               break;
243          }
244      }
245
246      return;
247
248 }
249
250
251 int main(int argc, char *argv[]) {
252      fin>>cities;
253      for(int x=1;x<=cities;x++){
254          fin>>gao[x];
255      }
256
257      for(int x=1;x<=cities-1;x++){
258          yuchu(x);
259          //fout<<x<<endl;
260          //fout<<dao[x][0]<<" "<<dao[x][1]<<endl;
261      }
262      //fout<<endl;
263      for(int x=1;x<=cities;x++){
264          if(jiyi[x].nxt==0)
265         yuchu2(x);
266         //fout<<x<<" ";
267         //fout<<jiyi[x].cnt_a<<" "<<jiyi[x].cnt_b<<endl;
268      }
269
270      fin>>x0;
271
272      for(int x=1;x<=cities;x++){
273          bgao=gao[x];
274          b_city=x;
275          cha(x,x0);
276      }
277      cout<<sze_city<<endl;
278      fout<<sze_city<<endl;
279
280      int shu=0;
281      fin>>shu;
282      for(int x=1;x<=shu;x++){
283           int sx=0,xx=0;
284           fin>>sx>>xx;
285           ans_a=0,ans_b=0;
286          cha2(sx,xx);
287           cout<<ans_a<<" "<<ans_b<<endl;
288           fout<<ans_a<<" "<<ans_b<<endl;
289      }
290
291
292      return 0;
293 }
时间: 2024-10-09 09:13:32

【题解】开车旅行的相关文章

题解 P1081 【开车旅行】

Solution 开车旅行 题目大意:有\(n\)座城市,每座城市有一个海拔高度,你只能从编号小的往编号大的移动.定义两城市距离为海拔高度差的绝对值.小A开车会去离他第二近的城市,小B开车会去离他最近的城市.(如果距离相同则认为海拔低的近).两人开车的距离之和不能超过\(X\),问给定一个\(X\)从哪座城市出发小A小B行驶距离之比最小,(一样小的认为海拔高的小),问给定出发点\(s\)和\(X\),小A小B分别行驶距离 倍增 分析:首先关键在于给定\(s\)和\(X\)的时候快速算出他俩分别走

noip2012 开车旅行

P1081 开车旅行 139通过 484提交 题目提供者洛谷OnlineJudge 标签倍增2012NOIp提高组 难度提高+/省选- 提交该题 讨论 题解 记录 题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 i 和城市 j 之间的距离 d[i,j]恰好是这两个城市海拔高度之差的绝对值,即 d[i,j] = |Hi− Hj|. 旅行过程中,小

洛谷P1081 开车旅行

P1081 开车旅行 152通过 524提交 题目提供者洛谷OnlineJudge 标签倍增NOIp提高组2012 难度省选/NOI- 提交该题 讨论 题解 记录 最新讨论 我前排提醒一下 题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 i 和城市 j 之间的距离 d[i,j]恰好是这两个城市海拔高度之差的绝对值,即 d[i,j] = |Hi−

codevs 1199 开车旅行 2012年NOIP全国联赛提高组

1199 开车旅行 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小A 和小B决定利用假期外出旅行,他们将想去的城市从1到N 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i的海拔高度为Hi,城市 i 和城市 j 之间的距离 d[i,j]恰好是这两个城市海拔高度之差的绝对值,即d[i, j] = |Hi − Hj|. 旅行过程中,小A 和小B轮流开

2012Noip提高组Day1 T3 开车旅行

题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 i 和城市 j 之间的距离 d[i,j]恰好是这两个城市海拔高度之差的绝对值,即 d[i,j] = |Hi− Hj|. 旅行过程中,小 A 和小 B 轮流开车,第一天小 A 开车,之后每天轮换一次.他们计划 选择一个城市 S 作为起点,一直向东行驶,并且最多行驶 X 公里就结束旅行.小 A 和小 B

开车旅行

洛谷P1081 开车旅行  NOIP 2012 提高组 第一天 第三题 题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 i 和城市 j 之间的距离 d[i,j]恰好是这两个城市海拔高度之差的绝对值,即 d[i,j] = |Hi− Hj|. 旅行过程中,小 A 和小 B 轮流开车,第一天小 A 开车,之后每天轮换一次.他们计划 选择一个城市 S 作

习题:开车旅行(倍增+预处理)

开车旅行(NOIP提高组2012) [描述]小A和小B决定利用假期外出旅行,他们将想去的城市从1到N编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市i 的海拔高度为Hi,城市i 和城市j 之间的距离d[i,j]恰好是这两个城市海拔高度之差的绝对值,即d[i,j] = |Hi - Hj|.旅行过程中,小A和小B轮流开车,第一天小A开车,之后每天轮换一次.他们计划选择一个城市S作为起点,一直向东行驶,并且最多行驶X公里就结束旅行.小A和小B的驾驶风格不同,小B总是

【noip2012】开车旅行 [倍增]

开车旅行 倍增 详细版 可以发现每个起点出发后面选择的城市都是一定的 所以预处理出\(to[i][j],da[i][j],db[i][j]\)表示从\(i\)出发小\(A\)和小\(B\)经过\(2^j\)轮后到达的地点.小\(A\)走的路程.小\(B\)走的路程 预处理时询问第一近和第二近的地点用双向链表 双向链表 不仅记录当前元素的下一个元素\((next)\)还记录当前元素的上一个元素\((pre)\) 数组版: int head,tail,tot; struct Node{ int va

【NOIP2012】开车旅行

题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 i 和城市 j 之间的距离 d[i,j]恰好是这两个城市海拔高度之差的绝对值,即 d[i,j] = |Hi? Hj|. 旅行过程中,小 A 和小 B 轮流开车,第一天小 A 开车,之后每天轮换一次.他们计划 选择一个城市 S 作为起点,一直向东行驶,并且最多行驶 X 公里就结束旅行.小 A 和小 B