Solution

Memo

  • 간단한 정렬 문제 2
  • 비교자만 잘 구현해두면 고민없이 풀리는 문제
  • 러스트 입출력을 좀 우아하게 할 수 있는 것 같다.
// Baekjoon - 23246
// https://www.acmicpc.net/problem/23246
use std::cmp::Ordering;
use std::io::{self, Read, Write};

#[derive(Debug)]
struct Climber {
    id: i32,
    lead: i32,
    spead: i32,
    boldering: i32,
}

impl Climber {
    fn total(&self) -> i32 {
        self.lead * self.spead * self.boldering
    }

    fn sum(&self) -> i32 {
        self.lead + self.spead + self.boldering
    }
}

impl Ord for Climber {
    fn cmp(&self, other: &Self) -> Ordering {
        self.total()
            .cmp(&other.total())
            .then_with(|| self.sum().cmp(&other.sum()))
            .then_with(|| self.id.cmp(&other.id))
    }
}

impl PartialOrd for Climber {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl PartialEq for Climber {
    fn eq(&self, other: &Self) -> bool {
        self.id == other.id
    }
}

impl Eq for Climber {}

fn main() -> io::Result<()> {
    let mut input = String::new();
    io::stdin().read_to_string(&mut input)?;
    let mut lines = input.lines();

    let n: usize = lines.next().unwrap().parse().unwrap();

    let mut climbers: Vec<Climber> = lines
        .take(n)
        .map(|line| {
            let nums: Vec<i32> = line
                .split_whitespace()
                .map(|s| s.parse().unwrap())
                .collect();

            Climber {
                id: nums[0],
                lead: nums[1],
                spead: nums[2],
                boldering: nums[3],
            }
        })
        .collect();

    climbers.sort();

    let result = climbers
        .iter()
        .take(3)
        .map(|c| c.id.to_string())
        .collect::<Vec<_>>()
        .join(" ");

    write!(io::stdout(), "{}", result)?;

    Ok(())
}
  • ord (comparator)만 잘 구현해두면 되는 매우 단순한 구현문제.
    let mut climbers: Vec<Climber> = lines
        .take(n)
        .map(|line| {
            let nums: Vec<i32> = line
                .split_whitespace()
                .map(|s| s.parse().unwrap())
                .collect();

            Climber {
                id: nums[0],
                lead: nums[1],
                spead: nums[2],
                boldering: nums[3],
            }
        })
        .collect();
  • 코틀린에서는 잘 되는데 러스트에서는 입력을 이렇게 깔끔하게 하는게 잘 안되는 것 같다.
import java.io.BufferedReader
import java.io.InputStreamReader

data class Climber(
    val id: Int,
    val lead: Int,
    val speed: Int,
    val bouldering: Int,
): Comparable<Climber> {
    private val total: Int
        get() = lead * speed * bouldering
    private val sum: Int
        get() = lead + speed + bouldering

    override fun compareTo(other: Climber): Int {
        return compareValuesBy(this, other,
            {it.total}, {it.sum}, {it.id}
        )
    }
}



fun main() = with(BufferedReader(InputStreamReader(System.`in`))) {
    val n = readLine().toInt()
    val climbers: MutableList<Climber> = mutableListOf()
    repeat(n) {
        val tmp = readLine()!!.split(" ").map { it.toInt() }
        climbers.add(Climber(tmp[0], tmp[1], tmp[2], tmp[3]))
    }
    val sortedClimbers = climbers.sorted()
    println(sortedClimbers.take(3).joinToString(" ") { it.id.toString() })
    close()
}