アットウィキロゴ

全体公開 > 合同練習会 > 20130323 > D 恋人同士の移動時間

問題の概要

平面上に, x軸 又は y軸に平行な線分が壁として一本与えられる.
また, 2人が居る点が与えられる.
彼らが会うのにかかる最短時間を求めよ.
ただし, 壁は超えられず, 壁上の両側では会った事にならず, 1単位距離動くのに1単位時間かかる.

実装の方針, 注意点

+ ...
二人の位置を A, B とし, 壁を PQ とする.
ABPQ が交わる場合, AP+PB, AQ+QB の短い方, そうでない場合は AB が通る道になる.

線分と線分の交差判定ライブラリは, Spaghetti Source を参考に.

ソースコード

+ ...
  1. typedef complex<double> P;
  2. #define X real()
  3. #define Y imag()
  4. double dot(P a, P b){
  5. return (a * conj(b)).X;
  6. }
  7. double cross(P a, P b){
  8. return (a * conj(b)).Y;
  9. }
  10. int ccw(P a, P b, P c){
  11. b -= a;
  12. c -= a;
  13. if(cross(b, c) > 0) return +1;
  14. if(cross(b, c) < 0) return -1;
  15. if(dot(b, c) < 0) return +2;
  16. if(norm(b) < norm(c)) return -2;
  17. return 0;
  18. }
  19. double dist(P a, P b){
  20. return abs(a - b);
  21. }
  22. bool intersectSS(const vector<P> &a, const vector<P> &b){
  23. return ccw(a[0], a[1], b[0]) * ccw(a[0], a[1], b[1]) <= 0 &&
  24. ccw(b[0], b[1], a[0]) * ccw(b[0], b[1], a[1]) <= 0;
  25. }
  26. bool solve(){
  27. vector<P> a(2), b(2);
  28. rep(i, 2) cin >> a[i].X >> a[i].Y;
  29. if(a[0] == P(0, 0) && a[1] == P(0, 0)) return false;
  30. rep(i, 2) cin >> b[i].X >> b[i].Y;
  31.  
  32. if(intersectSS(a, b)){
  33. double mn = INF;
  34. rep(i, 2) mineq(mn, dist(a[0], b[i]) + dist(a[1], b[i]));
  35. cout << mn/2 << endl;
  36. }else{
  37. cout << dist(a[0], a[1])/2 << endl;
  38. }
  39. return true;
  40. }
  41.  



最終更新:2013年03月27日 00:18