結果
問題 | No.5004 Room Assignment |
ユーザー |
![]() |
提出日時 | 2021-12-03 02:09:10 |
言語 | Rust (1.83.0 + proconio) |
結果 |
AC
|
実行時間 | 147 ms / 5,000 ms |
コード長 | 11,131 bytes |
コンパイル時間 | 2,237 ms |
実行使用メモリ | 22,380 KB |
スコア | 138,783,411 |
平均クエリ数 | 7617.98 |
最終ジャッジ日時 | 2021-12-03 02:09:32 |
合計ジャッジ時間 | 21,287 ms |
ジャッジサーバーID (参考情報) |
judge11 / judge15 |
純コード判定しない問題か言語 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 100 |
ソースコード
#![allow(unused_imports)]#![allow(dead_code)]#![allow(unused_macros)]use std::{collections::{VecDeque, HashSet}, io::{StdoutLock, prelude::*}, writeln};use std::io::{BufWriter};pub fn readln() -> String {let mut line = String::new();::std::io::stdin().read_line(&mut line).unwrap_or_else(|e| panic!("{}", e));line}macro_rules! read {($($t:tt),*; $n:expr) => {{let stdin = ::std::io::stdin();let ret = ::std::io::BufRead::lines(stdin.lock()).take($n).map(|line| {let line = line.unwrap();let mut it = line.split_whitespace();_read!(it; $($t),*)}).collect::<Vec<_>>();ret}};($($t:tt),*) => {{let line = readln();let mut it = line.split_whitespace();_read!(it; $($t),*)}};}macro_rules! _read {($it:ident; [char]) => {_read!($it; String).chars().collect::<Vec<_>>()};($it:ident; [u8]) => {Vec::from(_read!($it; String).into_bytes())};($it:ident; usize1) => {$it.next().unwrap_or_else(|| panic!("input mismatch")).parse::<usize>().unwrap_or_else(|e| panic!("{}", e)) - 1};($it:ident; [usize1]) => {$it.map(|s| s.parse::<usize>().unwrap_or_else(|e| panic!("{}", e)) - 1).collect::<Vec<_>>()};($it:ident; [$t:ty]) => {$it.map(|s| s.parse::<$t>().unwrap_or_else(|e| panic!("{}", e))).collect::<Vec<_>>()};($it:ident; $t:ty) => {$it.next().unwrap_or_else(|| panic!("input mismatch")).parse::<$t>().unwrap_or_else(|e| panic!("{}", e))};($it:ident; $($t:tt),+) => {($(_read!($it; $t)),*)};}const T: usize = 3600;const B: usize = 200;const INF: usize = 1000000007;const V: [usize; 5] = [0, 0, 1, 3, 6];struct Room {s_max: usize,s_min: usize,ticks: Vec<usize>,cost: usize,score: usize,player_sk: Vec<usize>,player_id: Vec<usize>,used: bool,}fn calc_score(room: &Room, t: usize, s: usize) -> usize {let mut e = 0;let n = room.ticks.len();for i in 0..n {e += t - room.ticks[i];}let mn = room.s_min.min(s);let mx = room.s_max.max(s);(V[n+1] * (B.saturating_sub((mx - mn) * (mx - mn)))).saturating_sub(e+room.cost)}fn calc_score2(room1: &Room, room2: &Room, t: usize) -> usize {let mut e = 0;let n1 = room1.ticks.len();let n2 = room2.ticks.len();for i in 0..n2 {e += (t - room2.ticks[i])*2;}for i in 0..n1 {e += (t - room1.ticks[i])*2;}let mn = room1.s_min.min(room2.s_min);let mx = room1.s_max.max(room2.s_max);(V[4] * (B.saturating_sub((mx - mn) * (mx - mn)))).saturating_sub(e+room1.cost+room2.cost)}fn main() {//let mut buffer = String::new();//std::io::stdin().read_to_string(&mut buffer).unwrap();//let mut input = buffer.split_whitespace();/*input!{input,n: usize,mut a: [usize; n]}*/let stdout = std::io::stdout();let mut stdout = BufWriter::new(stdout.lock());let (_, _) = read!(usize, usize);let mut rooms: Vec<Room> = Vec::new();let mut num_player = 0;//let mut rem = HashSet::new();for ti in 0..T {//let n = read!(usize);let sv = readln();let sv: Vec<&str> = sv.split_whitespace().collect();let n = sv[0].parse::<usize>().unwrap();let mut ret: Vec<(usize, usize)> = vec![];for ii in 0..n {num_player += 1;let si = sv[ii+1].parse::<usize>().unwrap();let mut mx = 100;let mut room_id = INF;for (id, ri) in rooms.iter().enumerate() {if ri.ticks.len() == 4 || ri.used {continue;}let tmp_score = calc_score(ri, ti, si);let sp = ri.s_max.max(si) - ri.s_min.min(si);if mx < tmp_score && sp < 4 {mx = tmp_score;room_id = id;}}if room_id < INF {let mut co = 0;for &tti in rooms[room_id].ticks.iter() {co += ti - tti;}//mx = calc_score(&rooms[room_id], ti, si);ret.push((num_player, rooms[room_id].player_id[0]));rooms[room_id].player_id.push(num_player);rooms[room_id].s_max = rooms[room_id].s_max.max(si);rooms[room_id].s_min = rooms[room_id].s_min.min(si);rooms[room_id].score = mx;rooms[room_id].ticks.push(ti);rooms[room_id].player_sk.push(si);rooms[room_id].cost += co;}else {rooms.push(Room{s_max: si, s_min: si, ticks: vec![ti], score: 0, player_id: vec![num_player], player_sk: vec![si], cost: 0, used:false});}}if (ti+1) % 18 == 0 {let r = rooms.len().min(20);let rn = rooms.len();for r1 in rn-r..rn {if rooms[r1].used || rooms[r1].ticks.len() != 2 {continue;}let mut mx = 800;let mut room_id = INF;for r2 in rn-r..rn {if rooms[r2].used || rooms[r2].ticks.len() != 2 || r1 == r2 {continue;}let tmp_score = calc_score2(&rooms[r1], &rooms[r2], ti);if tmp_score > rooms[r2].score + rooms[r1].score && mx < tmp_score - rooms[r2].score - rooms[r1].score {mx = tmp_score - rooms[r2].score - rooms[r1].score;room_id = r2;}}if room_id < INF {let mut co = 0;for &tti2 in rooms[room_id].ticks.iter() {co += (ti - tti2)*2;}for &tti2 in rooms[r1].ticks.iter() {co += (ti - tti2)*2;}let pi = rooms[r1].player_id[0];ret.push((pi, rooms[room_id].player_id[0]));rooms[room_id].player_id.push(pi);let pi = rooms[r1].player_id[1];rooms[room_id].player_id.push(pi);rooms[room_id].s_max = rooms[room_id].s_max.max(rooms[r1].s_max);rooms[room_id].s_min = rooms[room_id].s_min.min(rooms[r1].s_min);rooms[room_id].score += mx + rooms[r1].score;let tic = rooms[r1].ticks[0];rooms[room_id].ticks.push(tic);let tic = rooms[r1].ticks[1];rooms[room_id].ticks.push(tic);let sk = rooms[r1].player_sk[0];rooms[room_id].player_sk.push(sk);let sk = rooms[r1].player_sk[1];rooms[room_id].player_sk.push(sk);rooms[room_id].cost += co;rooms[r1].used = true;}}}if (ti+1) % 36 == 0 {let r = rooms.len().min(40);let r2 = rooms.len().min(20);let rn = rooms.len();for r1 in rn-r..rn-r2 {if rooms[r1].used || rooms[r1].ticks.len() > 1 {continue;}let mut mx = 100;let mut room_id = INF;let si = rooms[r1].player_sk[0];let tti = rooms[r1].ticks[0];for r2 in rn-r..rn-r2 {if rooms[r2].used || rooms[r2].ticks.len() == 4 || r1 == r2 {continue;}let mut tmp_score = calc_score(&rooms[r2], ti, si);tmp_score = tmp_score.saturating_sub((ti-tti)*rooms[r2].ticks.len());let sp = rooms[r2].s_max.max(si) - rooms[r2].s_min.min(si);if tmp_score > rooms[r2].score && mx < tmp_score - rooms[r2].score && sp < 6 {mx = tmp_score - rooms[r2].score;room_id = r2;}}if room_id < INF {let mut co = 0;for &tti2 in rooms[room_id].ticks.iter() {co += ti - tti2;}co += (ti - tti)*rooms[room_id].ticks.len();let pi = rooms[r1].player_id[0];ret.push((pi, rooms[room_id].player_id[0]));rooms[room_id].player_id.push(pi);rooms[room_id].s_max = rooms[room_id].s_max.max(si);rooms[room_id].s_min = rooms[room_id].s_min.min(si);rooms[room_id].score += mx;rooms[room_id].ticks.push(tti);rooms[room_id].player_sk.push(si);rooms[room_id].cost += co;rooms[r1].used = true;}}}if ti+1 == T {let r = rooms.len().min(20);let rn = rooms.len();for r1 in rn-r..rn {if rooms[r1].used || rooms[r1].ticks.len() > 1 {continue;}let mut mx = 0;let mut room_id = INF;let si = rooms[r1].player_sk[0];let tti = rooms[r1].ticks[0];for r2 in rn-r..rn {if rooms[r2].used || rooms[r2].ticks.len() == 4 || r1 == r2 {continue;}let mut tmp_score = calc_score(&rooms[r2], ti, si);tmp_score = tmp_score.saturating_sub((ti-tti)*rooms[r2].ticks.len());//let sp = rooms[r2].s_max.max(si) - rooms[r2].s_min.min(si);if tmp_score > rooms[r2].score && mx < tmp_score - rooms[r2].score {mx = tmp_score - rooms[r2].score;room_id = r2;}}if room_id < INF {let mut co = 0;for &tti2 in rooms[room_id].ticks.iter() {co += ti - tti2;}co += (ti - tti)*rooms[room_id].ticks.len();let pi = rooms[r1].player_id[0];ret.push((pi, rooms[room_id].player_id[0]));rooms[room_id].player_id.push(pi);rooms[room_id].s_max = rooms[room_id].s_max.max(si);rooms[room_id].s_min = rooms[room_id].s_min.min(si);rooms[room_id].score += mx;rooms[room_id].ticks.push(tti);rooms[room_id].player_sk.push(si);rooms[room_id].cost += co;rooms[r1].used = true;}}}write!(&mut stdout, "{}\n", ret.len()).unwrap();for (ui, vi) in ret {write!(&mut stdout, "{} {}\n", ui, vi).unwrap();}stdout.flush().unwrap();}let mut tscore = 0;for room in rooms {if room.ticks.len() > 0 && !room.used{tscore += room.score;}}eprintln!("{}", tscore);}