开车旅行
(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 }