結果
問題 |
No.245 貫け!
|
ユーザー |
|
提出日時 | 2025-02-13 01:41:11 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 2,118 ms / 5,000 ms |
コード長 | 2,504 bytes |
コンパイル時間 | 1,169 ms |
コンパイル使用メモリ | 99,260 KB |
実行使用メモリ | 5,248 KB |
最終ジャッジ日時 | 2025-02-13 01:41:33 |
合計ジャッジ時間 | 20,602 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 16 |
ソースコード
#include <iostream> #include <vector> #include <algorithm> using namespace std; using ll = long long; struct Segment { int a, b, c, d; }; struct Point { int x, y; }; // 2次元ベクトルの外積を計算 inline ll cross(ll ax, ll ay, ll bx, ll by) { return ax * by - ay * bx; } // check 関数:直線 PQ が、点 R と S の間を通るか? int check(const Point &P, const Point &Q, const Point &R, const Point &S) { // PとQが同一なら何も意味がないので 0 を返す if(P.x == Q.x && P.y == Q.y) return 0; // ベクトル PQ, PR, PS を計算 ll pqx = Q.x - P.x, pqy = Q.y - P.y; ll prx = R.x - P.x, pry = R.y - P.y; ll psx = S.x - P.x, psy = S.y - P.y; // cross(PQ, PR) と cross(PQ, PS) の積が 0 以下なら、R と S は直線 PQ の両側(または PQ 上)にある ll cross1 = cross(pqx, pqy, prx, pry); ll cross2 = cross(pqx, pqy, psx, psy); return (cross1 * cross2 <= 0) ? 1 : 0; } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int N; cin >> N; vector<Segment> segs(N); for (int i = 0; i < N; i++) { cin >> segs[i].a >> segs[i].b >> segs[i].c >> segs[i].d; } int ans = 0; // 候補となる点 (px, py) を全探索 (-101 <= px,py <= 101) for (int px = -101; px <= 101; px++){ for (int py = -101; py <= 101; py++){ Point P {px, py}; // 各線分について、両端点それぞれを Q としてチェック for (int i = 0; i < N; i++){ int tmp = 0; // まずは線分 i の左側の端点を Q とする Point Q {segs[i].a, segs[i].b}; // 全ての線分について、直線 PQ が分断しているかを調べる for (int j = 0; j < N; j++){ Point R {segs[j].a, segs[j].b}; Point S {segs[j].c, segs[j].d}; tmp += check(P, Q, R, S); } ans = max(ans, tmp); // 次は線分 i の右側の端点を Q とする tmp = 0; Q = {segs[i].c, segs[i].d}; for (int j = 0; j < N; j++){ Point R {segs[j].a, segs[j].b}; Point S {segs[j].c, segs[j].d}; tmp += check(P, Q, R, S); } ans = max(ans, tmp); } } } cout << ans << "\n"; return 0; }