結果
| 問題 |
No.947 ABC包囲網
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-09-26 17:15:33 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,866 ms / 2,000 ms |
| コード長 | 1,904 bytes |
| コンパイル時間 | 2,812 ms |
| コンパイル使用メモリ | 94,764 KB |
| 最終ジャッジ日時 | 2025-01-14 22:29:45 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 60 |
ソースコード
#pragma GCC optimize("O3")
#include <stdio.h>
#include <algorithm>
#include <vector>
using namespace std;
constexpr double kEps = 1E-10;
constexpr int kN = int(4E3 + 10);
#define PB push_back
struct Point {
double x, y;
Point(double a, double b) {x = a, y = b;}
Point() {}
void in() {
scanf("%lf%lf", &x, &y);
return ;
}
inline Point operator -(Point b) const {return Point(x - b.x, y - b.y);}
inline Point operator /(double b) const {return Point(x / b, y / b);}
inline double operator *(Point b) const {return x * b.x + y * b.y;}
inline double operator ^(Point b) const {return x * b.y - y * b.x;}
};
struct Line {
double a, b, c;
Line(Point pa, Point pb) :a(pa.y - pb.y), b(pb.x - pa.x), c(pa ^ pb){}
};
const Point O(0, 0);
int dcmp(double x) {return x > kEps ? 1 : x < -kEps ? -1 : 0;}
inline Point line_intersection(Line l1, Line l2) {
return Point(-l1.b * l2.c + l1.c * l2.b, l1.a * l2.c - l1.c * l2.a) / (-l1.a * l2.b + l1.b * l2.a);
}
inline bool onsegment(Point p, Point a, Point b) {
return dcmp((a - p) * (b - p)) < -kEps;
}
int n;
Point p[kN];
bool cmp(int a, int b) {return (p[a] ^ p[b]) > kEps;}
int cnt(int x) {
vector<int> left, right;
int lpos = 0, rpos = 0, lsz, rsz, ans = 0;
Line l(p[x], O);
double tmp;
for (int i = 1; i <= n; i++) if (i != x) {
tmp = p[i] ^ p[x];
if (tmp < -kEps) left.PB(i);
else if (tmp > kEps) right.PB(i);
}
sort(left.begin(), left.end(), cmp);
sort(right.begin(), right.end(), cmp);
lsz = int(left.size());
rsz = int(right.size());
while (lpos < lsz) {
while (rpos < rsz) {
if (onsegment(O, line_intersection(l, Line(p[left[lpos]], p[right[rpos]])), p[x])) rpos++;
else break;
}
ans += rpos;
lpos++;
}
return ans;
}
int main() {
long long int ans = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++) p[i].in();
for (int i = 1; i <= n; i++) ans += cnt(i);
printf("%lld\n", ans / 3);
}