結果

問題 No.199 星を描こう
ユーザー PUPU
提出日時 2023-01-26 23:42:43
言語 Rust
(1.72.1)
結果
AC  
実行時間 1 ms / 2,000 ms
コード長 6,931 bytes
コンパイル時間 1,069 ms
コンパイル使用メモリ 156,320 KB
実行使用メモリ 4,380 KB
最終ジャッジ日時 2023-09-09 21:29:49
合計ジャッジ時間 2,343 ms
ジャッジサーバーID
(参考情報)
judge14 / judge11
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,376 KB
testcase_01 AC 1 ms
4,380 KB
testcase_02 AC 1 ms
4,376 KB
testcase_03 AC 1 ms
4,376 KB
testcase_04 AC 1 ms
4,376 KB
testcase_05 AC 1 ms
4,380 KB
testcase_06 AC 1 ms
4,376 KB
testcase_07 AC 1 ms
4,376 KB
testcase_08 AC 1 ms
4,380 KB
testcase_09 AC 1 ms
4,380 KB
testcase_10 AC 1 ms
4,376 KB
testcase_11 AC 1 ms
4,380 KB
testcase_12 AC 1 ms
4,380 KB
testcase_13 AC 1 ms
4,380 KB
testcase_14 AC 1 ms
4,376 KB
testcase_15 AC 1 ms
4,380 KB
testcase_16 AC 1 ms
4,380 KB
testcase_17 AC 1 ms
4,376 KB
testcase_18 AC 1 ms
4,380 KB
testcase_19 AC 1 ms
4,376 KB
testcase_20 AC 1 ms
4,376 KB
testcase_21 AC 1 ms
4,376 KB
testcase_22 AC 1 ms
4,376 KB
testcase_23 AC 1 ms
4,376 KB
testcase_24 AC 1 ms
4,380 KB
testcase_25 AC 1 ms
4,376 KB
testcase_26 AC 1 ms
4,380 KB
testcase_27 AC 1 ms
4,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

pub use input_helper::stdin_reader::*;

fn main() {
    let mut v: Vec<Point> = vec![];
    for _ in 0..5 {
        let (x, y): (f64, f64) = read_line();
        v.push(Point::new(x, y));
    }

    let ch = v.convex_hull();
    if ch.len() == 5 {
        println!("YES");
    } else {
        println!("NO");
    }
}

use std::ops::{Add, Sub};

#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
struct Point {
    x: f64,
    y: f64,
}

impl Point {
    pub fn new<T: Into<f64>>(x: T, y: T) -> Self {
        Self {
            x: x.into(),
            y: y.into(),
        }
    }
}

impl Add for Point {
    type Output = Self;

    fn add(self, rhs: Self) -> Self {
        Self {
            x: self.x + rhs.x,
            y: self.y + rhs.y,
        }
    }
}

impl Sub for Point {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self::Output {
        Self {
            x: self.x - rhs.x,
            y: self.y - rhs.y,
        }
    }
}

impl Point {
    /// 3D cross product of OA and OB vectors, (i.e. z-component of their
    /// 2D cross product, but remember that it is not defined in 2D).
    /// Return a positive value, if OAB makes a counter-clockwise turn,
    /// negative for clockwise turn, and zero if the points are collinear.
    pub fn cross_product(o: Self, a: Self, b: Self) -> f64 {
        (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x)
    }
}

trait ConvexHull {
    type Output;
    fn convex_hull(&mut self) -> Self::Output;
}

impl ConvexHull for Vec<Point> {
    type Output = Self;
    /// 与えられた点集合の凸包を解きます。
    ///
    /// # 制約
    ///
    /// `self`が浮動小数点の集合の場合、NaNが含まれているとPanicします。
    ///
    /// # 注意
    ///
    /// この関数は`self`に対してソートや重複の削除などの破壊的変更を行います。
    fn convex_hull(&mut self) -> Self::Output {
        if self.len() <= 1 {
            return self.to_vec();
        }

        self.sort_by(|a, b| a.partial_cmp(b).unwrap());
        self.dedup();

        // Build loewr hull.
        let mut lower: Vec<Point> = vec![];
        for p in self.iter() {
            while lower.len() >= 2
                && Point::cross_product(lower[lower.len() - 2], lower[lower.len() - 1], *p) <= 0.0
            {
                lower.pop();
            }
            lower.push(*p);
        }

        // Build upper hull.
        let mut upper: Vec<Point> = vec![];
        for p in self.iter().rev() {
            while upper.len() >= 2
                && Point::cross_product(upper[upper.len() - 2], upper[upper.len() - 1], *p) <= 0.0
            {
                upper.pop();
            }
            upper.push(*p);
        }

        // Last point of each list is omitted because it is repeated
        // at the beginning of the other list.
        lower.pop();
        upper.pop();

        // Concatenation of the lower and upper hulls gives the convex hull.
        lower.append(&mut upper);

        lower
    }
}

#[test]
fn convex_hull_test() {
    let mut t: Vec<Point> = vec![];
    for i in 0..10 {
        for j in 0..10 {
            t.push(Point::new(i, j));
        }
    }

    assert_eq!(
        t.convex_hull(),
        vec![
            Point { x: 0.0, y: 0.0 },
            Point { x: 9.0, y: 0.0 },
            Point { x: 9.0, y: 9.0 },
            Point { x: 0.0, y: 9.0 }
        ]
    );
}

pub mod input_helper {
    //! A simple input helper for competitive programming.

    pub mod stdin_reader {
        use super::read::Read;
        use std::iter::FromIterator;

        /// Reads a single line from standard input with the specified type(s).
        ///
        /// # Examples
        /// ```no_run
        /// let (n, x, y): (usize, i64, i64) = read_line();
        /// let a: Vec<i64> = read_line();
        /// ```
        pub fn read_line<T: Read>() -> T {
            let mut buf = String::new();
            std::io::stdin().read_line(&mut buf).unwrap();
            Read::read(&mut buf.split_whitespace()).unwrap()
        }

        /// Reads multiple lines from standard input with the specified collection.
        ///
        /// # Example
        /// ```no_run
        /// let n: usize = read_line();
        /// let p: Vec<(i64, i64)> = read_multiple_lines(n);
        /// ```
        pub fn read_multiple_lines<T: Read, B: FromIterator<T>>(n: usize) -> B {
            (0..n).map(|_| read_line()).collect()
        }
    }

    mod read {
        use std::str::SplitWhitespace;

        pub trait Read: Sized {
            fn read(input: &mut SplitWhitespace) -> Option<Self>;
        }

        macro_rules! impl_read_for_types {
        ( $( $t : ty ), * ) => { $(
            impl Read for $t {
                fn read(input: &mut SplitWhitespace) -> Option<Self> {
                    match input.next() {
                        Some(v) => v.parse().ok(),
                        None => None,
                    }
                }
            }
        ) * };
    }

        impl_read_for_types!(i8, i16, i32, i64, i128, isize, u16, u32, u64, u128, usize, f32, f64);

        impl Read for String {
            fn read(input: &mut SplitWhitespace) -> Option<Self> {
                match input.next() {
                    Some(v) => Some(v.to_string()),
                    None => None,
                }
            }
        }

        /// Read String as Vec<u8>
        impl Read for Vec<u8> {
            fn read(input: &mut SplitWhitespace) -> Option<Self> {
                match input.next() {
                    Some(v) => Some(v.to_string().into_bytes()),
                    None => None,
                }
            }
        }

        /// Read String as Vec<char>
        impl Read for Vec<char> {
            fn read(input: &mut SplitWhitespace) -> Option<Self> {
                match input.next() {
                    Some(v) => Some(v.to_string().chars().collect()),
                    None => None,
                }
            }
        }

        macro_rules! impl_read_for_tuple {
        ( $( $t : ident ), * ) => {
            impl<$( $t : Read ), * > Read for ( $( $t ), * ) {
                fn read(input: &mut SplitWhitespace) -> Option<Self> {
                    Some( ( $( $t::read(input).unwrap() ), * ) )
                }
            }
        };
    }

        impl_read_for_tuple!(A, B);
        impl_read_for_tuple!(A, B, C);
        impl_read_for_tuple!(A, B, C, D);
        impl_read_for_tuple!(A, B, C, D, E);
        impl_read_for_tuple!(A, B, C, D, E, F);

        /// Read a whole line as Vec<T>
        impl<T: Read> Read for Vec<T> {
            fn read(input: &mut SplitWhitespace) -> Option<Self> {
                let mut vec = Vec::new();
                while let Some(v) = T::read(input) {
                    vec.push(v);
                }
                Some(vec)
            }
        }
    }
}
0