Submission #18695232


Source Code Expand

use proconio::input;
use std::collections::VecDeque;
use rand::prelude::*;

struct Input {
    each_cost: i32,
    profits: Vec<Vec<i32>>
}

impl Input {
    fn new(cost: i32, p: Vec<Vec<i32>>) -> Input {
        Input {
            each_cost: cost,
            profits: p
        }
    }
}

struct Mining {
    row: usize,
    col: usize
}

impl Mining {
    fn new(r: usize, c: usize) -> Mining {
        Mining {
            row: r,
            col: c
        }
    }
}

fn main() {
    get_time();

    input! {
        each_cost:i32,
        profits:[[i32;50];50]
    }

    let input = Input::new(each_cost, profits);
    let results = annealing(&input);
    
    println!("{}", results.len());
    for r in results {
        println!("{} {}", r.row, r.col);
    }
}


fn annealing(input: &Input) -> Vec<Mining> {
    let mut mining = vec![vec![true;50];50];
    const TIME_LIMIT: f64 = 1.98;
    const TEMP0: f64 = 20.0;
    const TEMP1: f64 = 0.0;

    let (mut best_score, mut best_out) = calc_score(&mining, &input);
    let mut old_score = best_score;
    let mut rng = rand_pcg::Pcg64Mcg::new(998244353);
    let mut cnt = 0;
    let mut t = get_time() / TIME_LIMIT;
    
    while t < 1.0 {
        cnt += 1;
        let temp = TEMP0.powf(1.0 - t) * TEMP1.powf(t);
        let h = rng.gen_range(1, 6);
        let w = rng.gen_range(1, 6);
        let r = rng.gen_range(0, 50 + 1 - h);
        let c = rng.gen_range(0, 50 + 1 - w);
        
        let mut last = vec![vec![false; w];h];
        let mut mined_count = 0;

        for dr in 0..h {
            for dc in 0..w {
                if mining[r + dr][c + dc] {
                    mined_count += 1;
                    last[dr][dc] = mining[r + dr][c + dc];
                }
            }
        }

        let next = mined_count <= w * h / 2;

        for dr in 0..h {
            for dc in 0..w {
                mining[r + dr][c + dc] = next;
            }
        }

        let (score, out) = calc_score(&mining, &input);

        if score >= old_score || rng.gen_bool(f64::exp((score - old_score) as f64 / temp)) {
            old_score = score;
            //dbg!(score);
        } else {
            for dr in 0..h {
                for dc in 0..w {
                    mining[r + dr][c + dc] = last[dr][dc];
                }
            }
        }

        if score > best_score {
            best_score = score;
            best_out = out;
        }

        t = get_time() / TIME_LIMIT;
    }

    let time = get_time();
    dbg!(cnt);
    dbg!(best_score);
    dbg!(time);

    return best_out;
}

fn calc_score(mining: &Vec<Vec<bool>>, input: &Input) -> (i32, Vec<Mining>) {
    let mut score = 0;
    let mut queue = VecDeque::new();
    let mut seen = vec![vec![false;50];50];
    let mut result = vec![];

    for row in 0..50 {
        if mining[row][0] {
            queue.push_back(Mining::new(row, 0));
        }
        if mining[row][49] {
            queue.push_back(Mining::new(row, 49));
        }
    }

    for col in 1..49 {
        if mining[0][col] {
            queue.push_back(Mining::new(0, col));
        }
        if mining[49][col] {
            queue.push_back(Mining::new(49, col));
        }
    }

    while !queue.is_empty() {
        let current = queue.pop_front().unwrap();
        let row = current.row;
        let col = current.col;
        let mut count = 0;

        if seen[row][col] {
            continue;
        }

        seen[row][col] = true;
        result.push(current);

        if row == 0 || (seen[row - 1][col] && mining[row - 1][col]) {
            count += 1;
        }

        if row == 49 || (seen[row + 1][col] && mining[row + 1][col]) {
            count += 1;
        }

        if col == 0 || (seen[row][col - 1] && mining[row][col - 1]) {
            count += 1;
        }

        if col == 49 || (seen[row][col + 1] && mining[row][col + 1]) {
            count += 1;
        }

        score += input.profits[row][col] - input.each_cost / count;

        if row != 0 && (!seen[row - 1][col] && mining[row - 1][col]) {
            queue.push_back(Mining::new(row - 1, col));
        }

        if row != 49 && (!seen[row + 1][col] && mining[row + 1][col]) {
            queue.push_back(Mining::new(row + 1, col));
        }

        if col != 0 && (!seen[row][col - 1] && mining[row][col - 1]) {
            queue.push_back(Mining::new(row, col - 1));
        }

        if col != 49 && (!seen[row][col + 1] && mining[row][col + 1]) {
            queue.push_back(Mining::new(row, col + 1));
        }
    }

    return (score, result);
}

fn get_time() -> f64 {
	static mut STIME: f64 = -1.0;
	let t = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap();
	let ms = t.as_secs() as f64 + t.subsec_nanos() as f64 * 1e-9;
	unsafe {
		if STIME < 0.0 {
			STIME = ms;
		}
		ms - STIME
	}
}

Submission Info

Submission Time
Task A - マイニング
User terry_u16
Language Rust (1.42.0)
Score 3100833
Code Size 4856 Byte
Status AC
Exec Time 1988 ms
Memory 3424 KiB

Judge Result

Set Name test_ALL
Score / Max Score 3100833 / 10000000
Status
AC × 100
Set Name Test Cases
test_ALL test_01.txt, test_02.txt, test_03.txt, test_04.txt, test_05.txt, test_06.txt, test_07.txt, test_08.txt, test_09.txt, test_10.txt, test_100.txt, test_11.txt, test_12.txt, test_13.txt, test_14.txt, test_15.txt, test_16.txt, test_17.txt, test_18.txt, test_19.txt, test_20.txt, test_21.txt, test_22.txt, test_23.txt, test_24.txt, test_25.txt, test_26.txt, test_27.txt, test_28.txt, test_29.txt, test_30.txt, test_31.txt, test_32.txt, test_33.txt, test_34.txt, test_35.txt, test_36.txt, test_37.txt, test_38.txt, test_39.txt, test_40.txt, test_41.txt, test_42.txt, test_43.txt, test_44.txt, test_45.txt, test_46.txt, test_47.txt, test_48.txt, test_49.txt, test_50.txt, test_51.txt, test_52.txt, test_53.txt, test_54.txt, test_55.txt, test_56.txt, test_57.txt, test_58.txt, test_59.txt, test_60.txt, test_61.txt, test_62.txt, test_63.txt, test_64.txt, test_65.txt, test_66.txt, test_67.txt, test_68.txt, test_69.txt, test_70.txt, test_71.txt, test_72.txt, test_73.txt, test_74.txt, test_75.txt, test_76.txt, test_77.txt, test_78.txt, test_79.txt, test_80.txt, test_81.txt, test_82.txt, test_83.txt, test_84.txt, test_85.txt, test_86.txt, test_87.txt, test_88.txt, test_89.txt, test_90.txt, test_91.txt, test_92.txt, test_93.txt, test_94.txt, test_95.txt, test_96.txt, test_97.txt, test_98.txt, test_99.txt
Case Name Status Exec Time Memory
test_01.txt AC 1988 ms 3256 KiB
test_02.txt AC 1982 ms 3268 KiB
test_03.txt AC 1983 ms 2988 KiB
test_04.txt AC 1983 ms 3308 KiB
test_05.txt AC 1983 ms 3324 KiB
test_06.txt AC 1984 ms 3192 KiB
test_07.txt AC 1984 ms 3244 KiB
test_08.txt AC 1983 ms 3028 KiB
test_09.txt AC 1982 ms 3360 KiB
test_10.txt AC 1983 ms 3312 KiB
test_100.txt AC 1982 ms 3380 KiB
test_11.txt AC 1982 ms 3372 KiB
test_12.txt AC 1984 ms 3172 KiB
test_13.txt AC 1984 ms 3168 KiB
test_14.txt AC 1982 ms 3324 KiB
test_15.txt AC 1983 ms 3036 KiB
test_16.txt AC 1983 ms 3260 KiB
test_17.txt AC 1982 ms 3116 KiB
test_18.txt AC 1982 ms 3396 KiB
test_19.txt AC 1986 ms 3196 KiB
test_20.txt AC 1983 ms 2988 KiB
test_21.txt AC 1982 ms 3044 KiB
test_22.txt AC 1982 ms 3120 KiB
test_23.txt AC 1983 ms 3144 KiB
test_24.txt AC 1982 ms 3340 KiB
test_25.txt AC 1983 ms 3320 KiB
test_26.txt AC 1983 ms 3136 KiB
test_27.txt AC 1984 ms 3020 KiB
test_28.txt AC 1984 ms 3304 KiB
test_29.txt AC 1983 ms 3024 KiB
test_30.txt AC 1982 ms 3112 KiB
test_31.txt AC 1983 ms 3380 KiB
test_32.txt AC 1983 ms 3264 KiB
test_33.txt AC 1983 ms 3312 KiB
test_34.txt AC 1982 ms 3316 KiB
test_35.txt AC 1983 ms 3336 KiB
test_36.txt AC 1983 ms 3388 KiB
test_37.txt AC 1983 ms 3196 KiB
test_38.txt AC 1982 ms 3424 KiB
test_39.txt AC 1985 ms 3124 KiB
test_40.txt AC 1983 ms 3152 KiB
test_41.txt AC 1982 ms 3328 KiB
test_42.txt AC 1983 ms 3272 KiB
test_43.txt AC 1983 ms 3248 KiB
test_44.txt AC 1983 ms 3260 KiB
test_45.txt AC 1983 ms 3124 KiB
test_46.txt AC 1984 ms 3152 KiB
test_47.txt AC 1983 ms 3152 KiB
test_48.txt AC 1984 ms 3088 KiB
test_49.txt AC 1984 ms 3112 KiB
test_50.txt AC 1983 ms 3332 KiB
test_51.txt AC 1984 ms 3200 KiB
test_52.txt AC 1983 ms 3120 KiB
test_53.txt AC 1984 ms 3364 KiB
test_54.txt AC 1983 ms 3164 KiB
test_55.txt AC 1984 ms 3132 KiB
test_56.txt AC 1984 ms 3348 KiB
test_57.txt AC 1982 ms 3252 KiB
test_58.txt AC 1982 ms 3328 KiB
test_59.txt AC 1983 ms 3236 KiB
test_60.txt AC 1983 ms 3116 KiB
test_61.txt AC 1982 ms 3232 KiB
test_62.txt AC 1983 ms 3040 KiB
test_63.txt AC 1982 ms 3156 KiB
test_64.txt AC 1983 ms 2952 KiB
test_65.txt AC 1983 ms 3316 KiB
test_66.txt AC 1983 ms 3320 KiB
test_67.txt AC 1982 ms 3364 KiB
test_68.txt AC 1984 ms 3032 KiB
test_69.txt AC 1983 ms 3188 KiB
test_70.txt AC 1982 ms 3312 KiB
test_71.txt AC 1982 ms 3064 KiB
test_72.txt AC 1982 ms 3116 KiB
test_73.txt AC 1982 ms 3168 KiB
test_74.txt AC 1986 ms 3008 KiB
test_75.txt AC 1982 ms 3256 KiB
test_76.txt AC 1984 ms 3412 KiB
test_77.txt AC 1984 ms 3084 KiB
test_78.txt AC 1983 ms 3252 KiB
test_79.txt AC 1984 ms 3168 KiB
test_80.txt AC 1983 ms 3084 KiB
test_81.txt AC 1984 ms 3284 KiB
test_82.txt AC 1983 ms 3120 KiB
test_83.txt AC 1982 ms 3316 KiB
test_84.txt AC 1983 ms 3268 KiB
test_85.txt AC 1982 ms 3096 KiB
test_86.txt AC 1982 ms 3188 KiB
test_87.txt AC 1983 ms 3048 KiB
test_88.txt AC 1983 ms 3356 KiB
test_89.txt AC 1984 ms 3168 KiB
test_90.txt AC 1983 ms 3336 KiB
test_91.txt AC 1983 ms 3116 KiB
test_92.txt AC 1983 ms 3244 KiB
test_93.txt AC 1983 ms 3376 KiB
test_94.txt AC 1983 ms 3160 KiB
test_95.txt AC 1984 ms 3164 KiB
test_96.txt AC 1982 ms 3048 KiB
test_97.txt AC 1984 ms 3196 KiB
test_98.txt AC 1983 ms 3184 KiB
test_99.txt AC 1983 ms 3336 KiB