AOJ : 2003 - Railroad Conflict
問題概要
http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/description.jsp?id=2003&lang=jp
日本語の問題文があるので省略です
アルゴリズム
- A地点から交差点までの距離を、ライバルと自社とに分けて、全て列挙 (ABと交差しないのは無視)
- ライバルの交差点までの距離を配列 r に、自社の交差点までの距離を配列 s に入れる
- A地点から距離が近い順に、r と s をソート
- i=0,j=0
- r[i] と s[j] を見て、A地点から近い方を選ぶ
- r[i] を選んだなら、それと反対側を通る -> i++
- s[j] を選んだなら、それと同じ側を通る -> j++
- トンネル作る必要があるならカウント
- 5を繰り返す
プログラム
#include <iostream> #include <complex> #include <vector> #include <algorithm> using namespace std; #define EPS (1e-10) #define INF (P(999999999,999999999)) typedef complex<double> P; double cross(P a, P b) { return (a.real() * b.imag() - a.imag() * b.real()); } int is_intersected_ls(P a1, P a2, P b1, P b2) { return ( cross(a2-a1, b1-a1) * cross(a2-a1, b2-a1) < EPS ) && ( cross(b2-b1, a1-b1) * cross(b2-b1, a2-b1) < EPS ); } P intersection_ls(P a1, P a2, P b1, P b2) { P b = b2-b1; double d1 = abs(cross(b, a1-b1)); double d2 = abs(cross(b, a2-b1)); if(d1 + d2 == 0) return INF; double t = d1 / (d1 + d2); return a1 + (a2-a1) * t; } int main(void){ int n; cin>>n; while(n--){ P sa,sb; cin>>sa.real()>>sa.imag()>>sb.real()>>sb.imag(); int m; cin>>m; vector< pair<double,bool> > s,r; while(m--){ bool flgRS,flg; //flgRS : 0 - ライバル 1 - 自分 P a,b; cin>>a.real()>>a.imag()>>b.real()>>b.imag()>>flgRS>>flg; if(is_intersected_ls(a,b,sa,sb)){ P its = intersection_ls(a,b,sa,sb); if(its == INF) continue; double dist = abs(sa - its); if(flgRS) s.push_back(pair<double,bool>(dist,flg)); else r.push_back(pair<double,bool>(dist,flg)); } } sort(s.begin(),s.end()); sort(r.begin(),r.end()); bool flg = false, firstFlg = true; int ans = 0, i = 0, j = 0; while(i < r.size() || j < s.size()){ if(j == s.size() || i != r.size() && r[i].first < s[j].first){ if(!firstFlg && flg != !r[i].second) ans++; flg = !r[i].second; i++; } else{ if(!firstFlg && flg != s[j].second) ans++; flg = s[j].second; j++; } firstFlg = false; } cout<<ans<<endl; } return 0; }