質問編集履歴

1

現状の修正

2020/03/12 06:45

投稿

zenobread
zenobread

スコア44

test CHANGED
File without changes
test CHANGED
@@ -1,7 +1,5 @@
1
1
  ###やりたいこと
2
2
 
3
- 以下の問題を解きたい
4
-
5
3
 
6
4
 
7
5
  問.以下の問に答えなさい
@@ -120,103 +118,7 @@
120
118
 
121
119
  と出力する
122
120
 
123
-
124
-
125
-
126
-
127
- ##やったこと(自分なりの考え方)
128
-
129
- 最初は道中のガソリンスタンド全て寄ったと仮定し,最後に残っている
130
-
131
- ガソリン量をもとに「よらなくてもいいガソリンスタンド」を算出しようとしたが,
132
-
133
- 計算量が多いので断念.
134
-
135
-
136
-
137
-
138
-
139
- 現在は
140
-
141
-
142
-
143
- その時車Pが保有しているガソリンで進み、ガソリンスタンドは無視する
144
-
145
-
146
-
147
- どこか途中でガソリンが足りなくなった場合、まだ補給していない1つ前の
148
-
149
- ガソリンスタンドでガソリンを補給したものとし、車にあるガソリンと合算する。
150
-
151
- それでも足りなければさらにひとつ前のガソリンスタンドでガソリンを補給する、
152
-
153
- ということを繰り返す。
154
-
155
-
156
-
157
- 足りるなら次に進む
158
-
159
-
160
-
161
- を繰り返す計算をしています
162
-
163
-
164
-
165
- ##抱えている問題(省略可)
121
+ ##字数制限の関係で省略
166
-
167
- 先程の考えだと、
168
-
169
- 例)
170
-
171
- 10 2 4
172
-
173
- 1 10
174
-
175
- 2 3
176
-
177
- 3 1
178
-
179
- 4 1
180
-
181
- 6 1
182
-
183
-
184
-
185
- この場合
186
-
187
- 「2km先のガソリンスタンドで3L補給(現在2km地点で残り3L).
188
-
189
-
190
-
191
- 6km先のガソリンスタンドまでは足りないので(4km地点で残り1L)
192
-
193
- 1つ前の4km地点のガソリンスタンドで1L補給して
194
-
195
- 6km先のガソリンスタンドに到着(現在6km地点で0L).
196
-
197
-
198
-
199
- 目的地まで6km地点のガソリンスタンドからゴールまで4kmある。
200
-
201
- 足りないので、6km地点で補給する(現在6km地点で1L)
202
-
203
- それでも足りず3km地点のガソリンスタンドで補給したものとする.(現在6km地点で2L)
204
-
205
-
206
-
207
- それでも足りないが2,3,4km地点のガソリンスタンドはすでに補給している為
208
-
209
- 使用できない.其の為1km地点で10L補給したとする.(現在6km地点で12L)
210
-
211
-
212
-
213
- ゴールまで4L消費し最終のこっているのは8L」
214
-
215
- となる
216
-
217
-
218
-
219
- だが「1km地点で補給していれば他のガソリンスタンドで補給する必要はない」ので計算が狂う
220
122
 
221
123
 
222
124
 
@@ -234,38 +136,236 @@
234
136
 
235
137
 
236
138
 
237
- ##ソースコード
139
+ ##過去ソースコードは字数削減の為削除しました
140
+
141
+
142
+
143
+
144
+
145
+ #追記
146
+
147
+ miyabi_sunのご回答から
148
+
149
+
150
+
151
+ 1、現在の保有量で到達できるスタンドまで進む
152
+
153
+
154
+
155
+ 2、到達できないスタンドが見つかれば、一番最後に利用したスタンド(もしくはスタート地点)
156
+
157
+ から到達できる最後のガソリンスタンドまでのリストを作成する
158
+
159
+
160
+
161
+ 3、そのリストが1つでもあれば一番最後にいた地点からリスト内で最もガソリンを補給できるスタンドまで移動し、
162
+
163
+ 移動した分のガソリンを引いたのち補給できるガソリンを補給する。そして1に戻る
164
+
165
+
166
+
167
+ 4、もし先ほどのリストなければ既に通過したガソリンスタンドかつまだ利用していないガソリンスタンドのリストを作成する
168
+
169
+
170
+
171
+ 5、利用していないスタンドのリストが一つでもあれば、リスト内のスタンドでガソリンを補給したこととし
172
+
173
+ 現在のガソリン量に補給したガソリンを足す。これを最も多くガソリンを補給できるスタンドの中から順に行い、
174
+
175
+ 現在地から先へ進めるか確かめる。進めるならば3と同じ補給と移動の計算を行い1へ
176
+
177
+
178
+
179
+ 6、利用できるスタンドが一つもない、または通過したスタンド全てを利用してしまった場合ループを抜ける
180
+
181
+
182
+
183
+ 7、これを目的地に到達するまで行う
184
+
185
+
186
+
187
+ というプログラムを組みましたが、まだエラーが発生しているようです。
238
188
 
239
189
  ```python
240
190
 
241
- #諸事情によりガソリンスタンドをoasisと表現し、ガソリンをwaterと表現しています
242
-
243
- #ガソリンスタンド地点をソートする為自作クラスoasisClassを作っています
244
-
245
-
246
-
247
191
  class oasisClass():
248
192
 
249
- #引数1にはガソリンスタンドまでの距離、引数2にはガソリンスタンドで得られるガソリン量
250
-
251
193
  def __init__(self,kyori,water):
252
194
 
253
195
  self.kyori=kyori
254
196
 
255
197
  self.water=water
256
198
 
257
- #ガソリンスタンドまでの距離でソートできるようにする
258
-
259
199
  def __lt__(self,other):
260
200
 
261
201
  return self.kyori<other.kyori
262
202
 
263
-
264
-
265
203
  def __repr__(self):
266
204
 
267
205
  return repr((self.kyori,self.water))
268
206
 
207
+ #--__repr__まで同じ
208
+
209
+ def __eq__(self,other):
210
+
211
+ if not isinstance(other,oasisClass):
212
+
213
+ return False
214
+
215
+ return self.kyori==other.kyori and self.water==other.water
216
+
217
+ def __hash__(self):
218
+
219
+ return hash(self.kyori)
220
+
221
+
222
+
223
+ def looping(current_oasis,oasis_list,current,oasis_set):#前から順に現在地(ガソリンスタンドのインデックス),ガソリンスタンド全体のリスト(スタート地点とゴール地点も含めた),現在のスタートからの距離と
224
+
225
+ #現在保有しているガソリンの量を示すクラスオブジェクト,補給に使用したガソリンスタンドのset
226
+
227
+ loop_break=False
228
+
229
+ for p in range(current_oasis,len(oasis_list)):#現在地から
230
+
231
+ if current.water+current.kyori>=oasis_list[len(oasis_list)-1].kyori:#目的地につけるか
232
+
233
+ oasis_last=oasis_list[len(oasis_list)-1]
234
+
235
+ current_oasis=oasis_list.index(oasis_last)
236
+
237
+ current.water+=oasis_last.water-(oasis_last.kyori-current.kyori)
238
+
239
+ current.kyori=oasis_last.kyori
240
+
241
+ return len(oasis_set)
242
+
243
+
244
+
245
+ if current.water+current.kyori>=oasis_list[p].kyori:#次のガソリンスタンドまでたどり着けるなら
246
+
247
+ continue#さらに次のガソリンスタンドへ
248
+
249
+ else:#現在のガソリンではたどり着けないスタンドが見つかったら
250
+
251
+ pre_oasis_list=[oasis_list[j] for j in range(current_oasis,p) if current.water+current.kyori>=oasis_list[j].kyori and oasis_list[j] not in oasis_set]
252
+
253
+ #現在地点から到達可能地点までのガソリンスタンド
254
+
255
+ if len(pre_oasis_list)>0:#現在のガソリンでたどり着けるガソリンスタンドがあれば
256
+
257
+ pre_oasis_list2=sorted(pre_oasis_list,key=lambda k:k.water)#ガソリン補給量の多い順にソート
258
+
259
+ pre_oasis_last=pre_oasis_list2[len(pre_oasis_list2)-1]
260
+
261
+ current_oasis=oasis_list.index(pre_oasis_last)#利用したガソリンスタンドのインデックスを検索
262
+
263
+ #ガソリンスタンドで補給した量からそれまでの距離で引く
264
+
265
+ current.water+=pre_oasis_last.water-(pre_oasis_last.kyori-current.kyori)
266
+
267
+ #スタート地点からの距離を代入
268
+
269
+ current.kyori=pre_oasis_last.kyori
270
+
271
+ #利用したガソリンスタンドをsetがたに保存
272
+
273
+ oasis_set.add(pre_oasis_last)
274
+
275
+ break
276
+
277
+ #ここで次のループに入る
278
+
279
+ else:#到達できるところがない場合
280
+
281
+ #既に通過したスタンドかつまだ利用していないところから補給する
282
+
283
+ pre_oasis_list2=[oasis_list[j] for j in range(1,current_oasis) if oasis_list[j] not in oasis_set]
284
+
285
+ pre_oasis_list2.sort(key=lambda u:u.water)
286
+
287
+ pre_all=0
288
+
289
+ if len(pre_oasis_list2)>0:#まだ補給していないところがあれば
290
+
291
+ for idx,h in enumerate(reversed(pre_oasis_list2)):
292
+
293
+ pre_all+=h.water#他のガソリンスタンドにもよる可能性があるのでいったん貯める
294
+
295
+ if pre_all+current.water+current.kyori>=oasis_list[len(oasis_list)-1].kyori:#ためたガソリンで目的地にまで到達すれば
296
+
297
+ oasis_last=oasis_list[len(oasis_list)-1]
298
+
299
+ current.water+=pre_all#ためたガソリンを補給
300
+
301
+ oasis_set.add(h)#利用したガソリンスタンドとして保存
302
+
303
+ current.water+=oasis_last.water-(oasis_list_last.kyori-current.kyori)
304
+
305
+ current.kyori=oasis_last.kyori
306
+
307
+ current_oasis=oasis_list.index(oasis_last)
308
+
309
+ return len(oasis_set)
310
+
311
+
312
+
313
+ if pre_all+current.water+current.kyori>=oasis_list[p].kyori:#ためたガソリンで次の目的地にまで到達すれば
314
+
315
+ #それまで貯めたガソリンを貯蓄
316
+
317
+ #利用したスタンドとして保存
318
+
319
+ current.water+=pre_all
320
+
321
+ oasis_set.add(h)
322
+
323
+ #ここからは次の地点に到達したものとして処理
324
+
325
+ current.water+=oasis_list[p].water-(oasis_list[p].kyori-current.kyori)
326
+
327
+ current.kyori=oasis_list[p].kyori
328
+
329
+ current_oasis=oasis_list.index(oasis_list[p])
330
+
331
+ oasis_set.add(oasis_list[p])
332
+
333
+ break
334
+
335
+ elif idx==0:#全てのスタンドを利用しても到達しなければ
336
+
337
+ loop_break=True#全てのループを抜ける
338
+
339
+ break
340
+
341
+ else:#全てのスタンを利用していないが到達していない場合
342
+
343
+ oasis_set.add(h)#利用したスタンドとして保存
344
+
345
+ continue
346
+
347
+ else:
348
+
349
+ break
350
+
351
+ else:#全てのガソリンスタンドを既に利用していたら
352
+
353
+ loop_break=True
354
+
355
+ break
356
+
357
+
358
+
359
+ if loop_break==False:#再ループ
360
+
361
+ return looping(current_oasis,oasis_list,current,oasis_set)
362
+
363
+ else:
364
+
365
+ return 0
366
+
367
+
368
+
269
369
 
270
370
 
271
371
  input_line = input()
@@ -278,13 +378,7 @@
278
378
 
279
379
  oasis=int(kyori0_saisyoryo1_oasiskazu2[2])
280
380
 
281
- #kyori=目的地までの距離 ryo=最初保有しているガソリン量 oasis=道中にあるガソリンスタンドの数
381
+
282
-
283
-
284
-
285
- #入力するガソリンスタンドは順不同なので、リストに入れてソートする
286
-
287
- #最初車に保有するガソリンを表現する為リストの最初に、0kmでryoだけガソリンを獲得する、という風にしている
288
382
 
289
383
  pre_oasis_list=[oasisClass(0,ryo)]
290
384
 
@@ -294,140 +388,22 @@
294
388
 
295
389
  pre_oasis_list.append(oasisClass(int(input_line[0]),int(input_line[1])))
296
390
 
297
- pre_oasis_list.append(oasisClass(int(kyori),0))#ゴール地点では0Lのガソリンを獲得する、というふうにしてリストに代入している
391
+ pre_oasis_list.append(oasisClass(int(kyori),0))
298
-
299
- oasis_list=sorted(pre_oasis_list)#スタート、ゴール地点すべて含めた地点リストを距離順にソート
392
+
300
-
301
-
302
-
303
- hokyu_sum=0#補給したガソリンの合計
304
-
305
- hokyu_set=set()#距離set型に保存
306
-
307
- hokyu_list=[]#距離をキーとしてガソリン量を保存
308
-
309
- current_ryo=ryo#現在のガソリン量
310
-
311
-
312
-
313
- #地点リストごとにループ
314
-
315
- for i in range(0,len(oasis_list)):
316
-
317
- current_ryo-=oasis_list[i].kyori
318
-
319
- if i!=0: current_ryo+=oasis_list[i-1].kyori
320
-
321
- if i!=0 and current_ryo<0:#次の地点へ着いた時点でガソリンがマイナスならさかのぼってガソリンを補給する
322
-
323
- pre_hokyu=0
324
-
325
- pre_set=set()
326
-
327
- pre_list=[]
328
-
329
- for p in reversed(range(1,i)):
330
-
331
- current=oasis_list[p]
332
-
333
- if current.kyori not in hokyu_set:#すでに補給場所に入っていないか
334
-
335
- if pre_hokyu>current.water:#それまで蓄えたガソリン量と比較して少ないなら補給
336
-
337
- #この先でまだまだ補給したり、今まで以上に補給したりする可能性もあるので暫定補給とする
338
-
339
- pre_hokyu+=current.water
340
-
341
- pre_set.add(current.kyori)
342
-
343
- pre_list.append(current)
344
-
345
- else:#その先で獲得するのと同じかそれ以上の水を獲得した場合
346
-
347
- #リセット処理
348
-
349
- pre_hokyu=current.water
350
-
351
- pre_set={current.kyori}
352
-
353
- pre_list=[current]
354
-
355
- if current_ryo+pre_hokyu>=0:
356
-
357
- break
358
-
359
- else:
360
-
361
- if i==1:#最初から補給してもダメならbreak
362
-
363
- break
364
-
365
- else:
366
-
367
- continue
368
-
369
- if current_ryo+pre_hokyu>0:#余分に補給していないかどうか
370
-
371
- #余分に補給しているなら捨てる
372
-
373
- pre_list.sort()
374
-
375
- for p in pre_list:
376
-
377
- if current_ryo+pre_hokyu-p.water>=0:#ガソリンを捨ててもマイナスにならないかどうか
378
-
379
- pre_set.remove(p)
380
-
381
- pre_list.remove(p)
382
-
383
- pre_hokyu-=p.water
384
-
385
- if current_ryo+pre_hokyu>0:
386
-
387
- continue
388
-
389
- else:
390
-
391
- break
392
-
393
- #ここで初めて確定処理
394
-
395
- if current_ryo+pre_hokyu>=0:#きちんと次の地点まで到達できているかどうか
396
-
397
- #地点に到達できているならループを続行
398
-
399
- hokyu_set=hokyu_set | pre_set
400
-
401
- hokyu_list.append(pre_list)
393
+ oasis_list=sorted(pre_oasis_list)
402
-
403
- hokyu_sum+=pre_hokyu
394
+
404
-
405
- current_ryo+=pre_hokyu
395
+ #input_lineからoasis_list=sorted...まで一緒
406
-
407
- else:
396
+
408
-
409
- #到達できないならここでループを抜ける
397
+
410
-
411
- current_ryo=-1
398
+
412
-
413
- break
414
-
415
- else:
416
-
417
- continue
418
-
419
- if current_ryo>=0:
399
+ current=oasisClass(pre_oasis_list[0].kyori,pre_oasis_list[0].water)#現在地と現在のガソリン量
420
-
421
- print(current_ryo)
400
+
422
-
423
- else:
424
-
425
- print("ガソリン足りない")
401
+ current_oasis=1#ガソリンスタンド全体のインデックス番号
402
+
403
+ oasis_set={oasis_list[0]}#最初のスタート地点を既に利用したものとして保存
404
+
405
+ print(looping(current_oasis,oasis_list,current,oasis_set)-1)
406
+
407
+
426
408
 
427
409
  ```
428
-
429
-
430
-
431
-
432
-
433
- よろしくお願いします