главная Π½ΠΎΠ²ΠΎΠ΅ Π»ΡƒΡ‡ΡˆΠ΅Π΅ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ

Бсылка Π½Π° Π·Π°Π΄Π°Ρ‡Ρƒ β€” 2033. Minimum Operations to Make a Uni-Value Grid.

πŸ“Œ ОписаниС Π·Π°Π΄Π°Ρ‡ΠΈ

Π”Π°Π½ Π΄Π²ΡƒΠΌΠ΅Ρ€Π½Ρ‹ΠΉ массив grid Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ m x n, Π° Ρ‚Π°ΠΊΠΆΠ΅ число x.
Π—Π° ΠΎΠ΄Π½Ρƒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΈΠ»ΠΈ Π²Ρ‹Ρ‡Π΅ΡΡ‚ΡŒ x ΠΈΠ· любого элСмСнта массива.
НуТно Π½Π°ΠΉΡ‚ΠΈ минимальноС количСство ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… для привСдСния всСх элСмСнтов grid ΠΊ ΠΎΠ΄Π½ΠΎΠΌΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ.
Если это Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ β€” Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ -1.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€

πŸ’‘ ИдСя

βš™οΈ Π”Π΅Ρ‚Π°Π»ΠΈ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π°

  1. Π‘Ρ‚Ρ€ΠΎΠΈΠΌ частотный массив
    • ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Ρ‡Ρ‚ΠΎ всС числа ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΉ остаток ΠΏΡ€ΠΈ Π΄Π΅Π»Π΅Π½ΠΈΠΈ Π½Π° x.
    • ΠŸΠΎΠ΄ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅ΠΌ количСство Π²Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠΉ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ числа, ΠΎΡ‚ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΊ val / x, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π°Π²ΠΈΡ‚ΡŒΡΡ ΠΎΡ‚ влияния x.
    • Находим ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΈ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ индСксы срСди Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡ‰ΠΈΡ…ΡΡ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Π²Ρ‹Ρ€Π΅Π·Π°Ρ‚ΡŒ минимально Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ΠΉ сСктор ΠΈΠ· Π²Π΅ΠΊΡ‚ΠΎΡ€Π° частот.
  2. Π˜Ρ‰Π΅ΠΌ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½ΡƒΡŽ ΠΎΠΏΠΎΡ€Π½ΡƒΡŽ Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρƒ
    • ΠžΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Π΅ΠΌ балансныС счётчики, проходя ΠΏΠΎ отсортированным значСниям Π² Π²Π΅ΠΊΡ‚ΠΎΡ€Π΅ частот.
    • ВычисляСм динамичСски количСство ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, ΠΏΠΎΠΎΡ‡Π΅Ρ€Ρ‘Π΄Π½ΠΎ провСряя всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ ΠΎΠΏΠΎΡ€Π½Ρ‹Π΅ Ρ‚ΠΎΡ‡ΠΊΠΈ.
  3. Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ минимальноС количСство ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ
    • Если условия выполнимости Π½Π΅ Π½Π°Ρ€ΡƒΡˆΠ΅Π½Ρ‹ β€” Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ ΠΎΡ‚Π²Π΅Ρ‚.
    • Π˜Π½Π°Ρ‡Π΅ β€” Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ -1.

⏳ Асимптотика

πŸ’» Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ ΠΊΠΎΠ΄

impl Solution {
    pub fn min_operations(grid: Vec<Vec<i32>>, x: i32) -> i32 {
        let total_cells = grid.len() * grid[0].len();

        // Get frequency counters for scaled values
        let mut counters_grid = match Self::get_counters_grid(grid, x) {
            Some(counters) => counters,
            None => return -1, // Impossible to make all values equal
        };

        // Compute initial sum of differences
        let mut sum_balance = counters_grid.iter()
            .enumerate()
            .map(|(value, &count)| value * count)
            .sum::<usize>();

        let mut cells_balance = total_cells;
        let mut min_ops = sum_balance;

        // Iterate over the frequency counter and adjust balances
        counters_grid.into_iter()
            .enumerate()
            .map(|(value, count)| {
                sum_balance -= 2 * value * count;
                cells_balance -= 2 * count;
                sum_balance - cells_balance * value
            })
            .min()
            .unwrap() as _
    }

    // Converts a 2D grid into a frequency counter for scaled values.
    // The transformation is impossible when at least two values in the grid have different remainders when divided by x.
    // Returns None if transformation is impossible.
    fn get_counters_grid(grid: Vec<Vec<i32>>, x: i32) -> Option<Vec<usize>> {
        const MAX_INDEX: usize = 10_000; // Upper bound for value indices
        let mut counters_grid = vec![0; MAX_INDEX + 1];

        let mod_base = grid[0][0] % x;
        let (mut min_index, mut max_index) = (MAX_INDEX, 0);

        for row in grid {
            for val in row {
                if val % x != mod_base {
                    return None; // Impossible transformation
                }
                let index = (val / x) as usize;
                max_index = max_index.max(index + 1);
                min_index = min_index.min(index);
                counters_grid[index] += 1;
            }
        }

        // Trim the counters grid to the relevant range
        Some(counters_grid[min_index..max_index].to_vec())
    }
}

Tags: #rust #algorithms #optimization