結果
問題 | No.2376 障害物競プロ |
ユーザー | milanis48663220 |
提出日時 | 2023-07-07 23:02:18 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 726 ms / 4,000 ms |
コード長 | 6,592 bytes |
コンパイル時間 | 1,619 ms |
コンパイル使用メモリ | 131,768 KB |
実行使用メモリ | 5,888 KB |
最終ジャッジ日時 | 2024-07-21 19:21:34 |
合計ジャッジ時間 | 59,969 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 378 ms
5,376 KB |
testcase_05 | AC | 527 ms
5,376 KB |
testcase_06 | AC | 223 ms
5,376 KB |
testcase_07 | AC | 726 ms
5,632 KB |
testcase_08 | AC | 722 ms
5,632 KB |
testcase_09 | AC | 708 ms
5,888 KB |
testcase_10 | AC | 714 ms
5,632 KB |
testcase_11 | AC | 642 ms
5,632 KB |
testcase_12 | AC | 632 ms
5,504 KB |
testcase_13 | AC | 689 ms
5,504 KB |
testcase_14 | AC | 694 ms
5,504 KB |
testcase_15 | AC | 648 ms
5,376 KB |
testcase_16 | AC | 703 ms
5,632 KB |
testcase_17 | AC | 632 ms
5,632 KB |
testcase_18 | AC | 614 ms
5,504 KB |
testcase_19 | AC | 653 ms
5,760 KB |
testcase_20 | AC | 660 ms
5,504 KB |
testcase_21 | AC | 668 ms
5,504 KB |
testcase_22 | AC | 554 ms
5,376 KB |
testcase_23 | AC | 394 ms
5,376 KB |
testcase_24 | AC | 394 ms
5,376 KB |
testcase_25 | AC | 184 ms
5,376 KB |
testcase_26 | AC | 452 ms
5,376 KB |
testcase_27 | AC | 375 ms
5,376 KB |
testcase_28 | AC | 233 ms
5,376 KB |
testcase_29 | AC | 187 ms
5,376 KB |
testcase_30 | AC | 246 ms
5,376 KB |
testcase_31 | AC | 236 ms
5,376 KB |
testcase_32 | AC | 32 ms
5,376 KB |
testcase_33 | AC | 102 ms
5,376 KB |
testcase_34 | AC | 123 ms
5,376 KB |
testcase_35 | AC | 76 ms
5,376 KB |
testcase_36 | AC | 431 ms
5,632 KB |
testcase_37 | AC | 505 ms
5,376 KB |
testcase_38 | AC | 183 ms
5,376 KB |
testcase_39 | AC | 553 ms
5,632 KB |
testcase_40 | AC | 206 ms
5,504 KB |
testcase_41 | AC | 171 ms
5,376 KB |
testcase_42 | AC | 692 ms
5,760 KB |
testcase_43 | AC | 695 ms
5,632 KB |
ソースコード
#include <iostream> #include <algorithm> #include <iomanip> #include <vector> #include <queue> #include <deque> #include <set> #include <map> #include <tuple> #include <cmath> #include <numeric> #include <functional> #include <cassert> #define debug_value(x) cerr << "line" << __LINE__ << ":<" << __func__ << ">:" << #x << "=" << x << endl; #define debug(x) cerr << "line" << __LINE__ << ":<" << __func__ << ">:" << x << endl; template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; } template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; } using namespace std; typedef long long ll; template<typename T> vector<vector<T>> vec2d(int n, int m, T v){ return vector<vector<T>>(n, vector<T>(m, v)); } template<typename T> vector<vector<vector<T>>> vec3d(int n, int m, int k, T v){ return vector<vector<vector<T>>>(n, vector<vector<T>>(m, vector<T>(k, v))); } template<typename T> void print_vector(vector<T> v, char delimiter=' '){ if(v.empty()) { cout << endl; return; } for(int i = 0; i+1 < v.size(); i++) cout << v[i] << delimiter; cout << v.back() << endl; } template<typename T> struct line { line(T a, T b, T c): a(a), b(b), c(c){}; T a, b, c; }; template<typename T> ostream& operator<<(ostream& os, const line<T>& l){ os << l.a << "*x + " << l.b << "*y+ " << l.c; return os; } template<typename T> inline T add(T a, T b){ return a+b; } const double eps = 1e-10; inline double add(double a, double b){ if(abs(a+b) < eps*(abs(a)+abs(b))) return 0.0; return a+b; } template<typename T> class point { public: point<T>(T x, T y): x(x), y(y){}; point<T>(): x(0), y(0){}; T x, y; point<T> operator + (point<T> p){ return point<T>(add(x, p.x), add(y, p.y)); }; point<T> operator - (point<T> p){ return point<T>(add(x, -p.x), add(y, -p.y)); }; point<T> operator * (T d){ return point<T>(x*d, y*d); }; T dot(point<T> p){ return add(x*p.x, y*p.y); }; T det(point<T> p){ return add(x*p.y, -y*p.x); }; }; /** * 直線lとp1, p2を結ぶ直線を求めます */ template<typename T> line<T> from_points(point<T> p1, point<T> p2){ return line(p2.y-p1.y, p1.x-p2.x, p1.y*p2.x-p1.x*p2.y); } /** * l: ax+by+c = 0としたときにax+by+cの値を返します */ template<typename T> T substitute(line<T> l, point<T> p){ return p.x*l.a+p.y*l.b+l.c; } /** * 直線lとp1, p2を結ぶ線分が交点を持つか否かを返します */ template<typename T> bool intersect(line<T> l, point<T> p1, point<T> p2){ return (substitute(l, p1) > 0) ^ (substitute(l, p2) > 0); } /** * p1, p2を結ぶ線分とq1, q2を結ぶ線分が交点を持つか否かを返します */ template<typename T> bool intersect(point<T> p1, point<T> p2, point<T> q1, point<T> q2){ auto lp = from_points(p1, p2); auto lq = from_points(q1, q2); bool fq = (substitute(lq, p1) > 0) ^ (substitute(lq, p2) > 0); bool fp = (substitute(lp, q1) > 0) ^ (substitute(lp, q2) > 0); return fp&&fq; } template<typename T> double dist(point<T> p1, point<T> p2){ T dx = p1.x-p2.x; T dy = p1.y-p2.y; return sqrt(dx*dx+dy*dy); } template<typename T> T dist_sq(point<T> p1, point<T> p2){ T dx = p1.x-p2.x; T dy = p1.y-p2.y; return dx*dx+dy*dy; } /** * 線分p1p2の垂直二等分線を求めます */ line<double> vertical_bisector(point<double> p1, point<double> p2){ double a = 2.0*(p2.x-p1.x); double b = 2.0*(p2.y-p1.y); double c = p2.x*p2.x-p1.x*p1.x+p2.y*p2.y-p1.y*p1.y; return line<double>(a, b, -c); } /** * 直線l1と直線l2がただ一つの交点を持つかを返します */ bool intersect(line<double> l1, line<double> l2){ if(abs(l1.a*l2.b-l2.a*l1.b) < eps) return false; return true; } /** * 直線l1と直線l2の交点を求めます * 戻り値をoptionalに書き換えるほうが良さそう */ point<double> intersection(line<double> l1, line<double> l2){ assert(intersect(l1, l2)); double x = l1.b*l2.c-l2.b*l1.c; double y = l2.a*l1.c-l1.a*l2.c; double d = l1.a*l2.b-l2.a*l1.b; return point<double>(x/d, y/d); } point<double> rot(double theta, point<double> p){ double x = p.x; double y = p.y; double c = cos(theta); double s = sin(theta); return point<double>(c*x-s*y, c*y+s*x); } const double INF = 1e+15; vector<vector<double>> warshallfloyd(vector<vector<double>> g){ int n = g.size(); vector<vector<double>> dist(n, vector<double>(n)); for(int i = 0; i < n; i++){ for(int j = 0; j < n; j++){ dist[i][j] = g[i][j]; } dist[i][i] = 0; } for(int i = 0; i < n; i++){ for(int j = 0; j < n; j++){ for(int k = 0; k < n; k++){ double new_len = dist[j][i] + dist[i][k]; dist[j][k] = min(new_len, dist[j][k]); } } } return dist; } using Po = point<int>; int main(){ ios::sync_with_stdio(false); cin.tie(0); cout << setprecision(10) << fixed; int n, m; cin >> n >> m; vector<vector<Po>> points; for(int i = 0; i < n; i++){ points.push_back({}); for(int j = 0; j < 2; j++){ int x, y; cin >> x >> y; points.back().push_back(Po(x, y)); } } auto to_idx = [&](int i, int j){ return i*2+j; }; auto g = vec2d(n*2, n*2, INF); for(int i = 0; i < n; i++){ for(int j = 0; j < 2; j++){ for(int k = 0; k < n; k++){ for(int l = 0; l < 2; l++){ if(i == k) continue; bool ok = true; for(int p = 0; p < n; p++){ if(p == i || p == k) continue; if(intersect(points[i][j], points[k][l], points[p][0], points[p][1])) ok = false; } if(ok){ int idx0 = to_idx(i, j); int idx1 = to_idx(k, l); g[idx0][idx1] = dist(points[i][j], points[k][l]); // cout << i << ' ' << j << "->" << k << ' ' << l << ':' << g[idx0][idx1] << endl; } } } } } auto dist = warshallfloyd(g); for(int i = 0; i < m; i++){ int a, b, c, d; cin >> a >> b >> c >> d; a--; b--; c--; d--; int i0 = to_idx(a, b); int i1 = to_idx(c, d); cout << dist[i0][i1] << endl; } }