結果
| 問題 |
No.3154 convex polygon judge
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-05-24 18:34:07 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 44 ms / 2,000 ms |
| コード長 | 3,779 bytes |
| コンパイル時間 | 12,131 ms |
| コンパイル使用メモリ | 391,876 KB |
| 実行使用メモリ | 15,008 KB |
| 最終ジャッジ日時 | 2025-05-24 18:34:24 |
| 合計ジャッジ時間 | 14,701 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 44 |
ソースコード
use convex_hull::convex_hull;
use proconio::input;
fn main() {
input! {
n: usize,
}
let points = {
let mut points = Vec::with_capacity(n);
for _ in 0..n {
input! { x: i64, y: i64 }
points.push([x, y]);
}
points
};
let hull = convex_hull(&points);
let ans = hull.len() == n;
println!("{}", if ans { "Yes" } else { "No" });
}
// convex_hull {{{
// https://ngtkana.github.io/ac-adapter-rs/convex_hull/index.html
#[allow(dead_code)]
mod convex_hull {
type Point = [i64; 2];
pub fn sqmag(p0: Point, p1: Point) -> i64 {
let [x0, y0] = p0;
let [x1, y1] = p1;
let dx = x0 - x1;
let dy = y0 - y1;
dx * dx + dy * dy
}
pub fn ccw(p0: Point, p1: Point, p2: Point) -> i64 {
let [x0, y0] = p0;
let [x1, y1] = p1;
let [x2, y2] = p2;
(x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0)
}
// det(p1 - p0, p3 - p2) を求めます。
fn general_ccw(p0: Point, p1: Point, p2: Point, p3: Point) -> i64 {
let [x0, y0] = p0;
let [x1, y1] = p1;
let [x2, y2] = p2;
let [x3, y3] = p3;
(x1 - x0) * (y3 - y2) - (x3 - x2) * (y1 - y0)
}
pub fn convex_hull(a: &[[i64; 2]]) -> Vec<[i64; 2]> {
if a.is_empty() {
Vec::new()
} else if a.len() == 1 {
vec![a[0]]
} else if a.len() == 2 {
if a[0] == a[1] {
vec![a[0]]
} else {
vec![a[0], a[1]]
}
} else {
let mut a = a.to_vec();
a.sort_unstable();
a.dedup();
let mut hull = Vec::new();
for &p in &a {
while 2 <= hull.len() && 0 <= ccw(hull[hull.len() - 2], hull[hull.len() - 1], p) {
hull.pop();
}
hull.push(p);
}
let mid_len = hull.len();
for &p in a.iter().rev().skip(1) {
while mid_len < hull.len()
&& 0 <= ccw(hull[hull.len() - 2], hull[hull.len() - 1], p)
{
hull.pop();
}
hull.push(p);
}
if hull.first().unwrap() == hull.first().unwrap() {
hull.pop();
}
hull
}
}
pub fn caliper(a: &[[i64; 2]]) -> (i64, [[i64; 2]; 2]) {
assert!(!a.is_empty());
let a = convex_hull(a);
if a.len() == 1 {
(0, [a[0], a[0]])
} else if a.len() == 2 {
(sqmag(a[0], a[1]), [a[0], a[1]])
} else {
let n = a.len();
let mut d = 0;
let mut ans_i = usize::MAX;
let mut ans_j = usize::MAX;
let min_position = (0..n).min_by_key(|&i| a[i][0]).unwrap();
let max_position = (0..n).max_by_key(|&i| a[i][0]).unwrap();
let start_i = min_position.min(max_position);
let start_j = min_position.max(max_position);
let mut i = start_i;
let mut j = start_j;
while i != start_i + n && j != start_j + n {
if 0 < general_ccw(a[(i + 1) % n], a[i % n], a[(j + 1) % n], a[j % n]) {
i += 1;
} else {
j += 1;
}
let e = sqmag(a[i % n], a[j % n]);
if d < e {
d = e;
ans_i = i;
ans_j = j;
}
}
(d, [a[ans_i % n], a[ans_j % n]])
}
}
pub fn is_convex(a: &[[i64; 2]]) -> bool {
a.len() <= 2 || (0..a.len() - 2).all(|i| ccw(a[i], a[i + 1], a[i + 2]) < 0)
}
}
// }}}