結果
| 問題 |
No.947 ABC包囲網
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-12-10 20:46:44 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 2,401 bytes |
| コンパイル時間 | 628 ms |
| コンパイル使用メモリ | 47,568 KB |
| 実行使用メモリ | 6,948 KB |
| 最終ジャッジ日時 | 2024-06-24 02:20:26 |
| 合計ジャッジ時間 | 60,417 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 38 TLE * 22 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:94:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
94 | scanf("%d", &n);
| ~~~~~^~~~~~~~~~
main.cpp: In member function ‘void Point::in()’:
main.cpp:18:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
18 | scanf("%lf", &tmp);
| ~~~~~^~~~~~~~~~~~~
main.cpp:20:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
20 | scanf("%lf", &tmp);
| ~~~~~^~~~~~~~~~~~~
ソースコード
bool debug = false;
#include <stdio.h>
#include <assert.h>
#include <algorithm>
#include <vector>
using namespace std;
constexpr long double kEps = 1E-10;
constexpr int kN = int(4E3 + 10), kInf = int(1E9 + 10);
#define PB push_back
struct Point {
long double x, y;
Point(long double a, long double b) {x = a, y = b;}
Point() {}
void in() {
double tmp;
scanf("%lf", &tmp);
x = tmp;
scanf("%lf", &tmp);
y = tmp;
return ;
}
Point operator -(Point b) const {return Point(x - b.x, y - b.y);}
Point operator /(long double b) {return Point(x / b, y / b);}
long double operator *(Point b) const {return x * b.x + y * b.y;}
long double operator ^(Point b) const {return x * b.y - y * b.x;}
};
struct Line {
long 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(long double x) {return x > kEps ? 1 : x < -kEps ? -1 : 0;}
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);
}
bool onsegment(Point p, Point a, Point b) {
return dcmp((a - p) * (b - p)) < -kEps;
}
int n;
Point p[kN];
int cnt(int x) {
vector<int> left, right;
int lpos = 0, rpos = 0, lsz, rsz, ans = 0;
Line l(p[x], O);
long 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);
}
auto cmp = [&](int a, int b) {return (p[a] ^ p[b]) > kEps;};
sort(left.begin(), left.end(), cmp);
sort(right.begin(), right.end(), cmp);
lsz = int(left.size());
rsz = int(right.size());
if (debug) {
printf("x = %d\n", x);
printf("-- left --\n");
for (int i : left) printf("%d\n", i);
printf("-- right --\n");
for (int i : right) printf("%d\n", i);
}
while (lpos < lsz) {
while (rpos < rsz) {
if (onsegment(O, line_intersection(l, Line(p[left[lpos]], p[right[rpos]])), p[x])) rpos++;
else break;
}
if (debug) printf("lpos = %d, rpos = %d\n", lpos, rpos);
ans += rpos;
lpos++;
}
if (debug) printf("ans = %d\n", ans);
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);
assert(ans % 3 == 0);
printf("%lld\n", ans / 3);
}