Submission #42958368
Source Code Expand
#![allow(non_snake_case)] use bitset_fixed::BitSet; use itertools::Itertools; use proconio::*; use std::collections::HashSet; fn main() { get_time(); let input = read_input(); let out = solve(&input); write_output(&out); eprintln!("Time = {:.3}", get_time()); } const W: usize = 2000; fn solve(input: &Input) -> Output { // 一番小さいボールから順に1つずつ適切な場所へ運ぶのを1ステップとしてビームサーチをする // 評価値は(手数, 下方向にボールを動かすたびにその数字を減算したもの)の辞書順 let mut beam = vec![State { bs: input.bs.clone(), id: !0, score: (0, 0), used: BitSet::new(N2), }]; let mut trace = Trace::new(); let mut dist = [((1000000000, 0), !0); N2]; for i in 0..N2 as i32 { eprintln!("{}: {}", i, beam[0].score.0); let mut trace2 = Trace::new(); // 高速化のため、次の状態を列挙するのではなく評価値と遷移方法のみを列挙する // (評価値, 現在のビームの何番目からか, 運ぶ先x, 運ぶ先y, 復元用ID) let mut next_move = vec![]; let pos: Vec<(usize, usize)> = beam.iter().map(|s| pos(&s.bs, i)).collect_vec(); for b in 0..beam.len() { let bs = &beam[b].bs; let (x0, y0) = pos[b]; dist[id(x0, y0)] = ((0, 0), !0); if x0 == 0 || (y0 == 0 || bs[id(x0 - 1, y0 - 1)] < i) && (y0 == x0 || bs[id(x0 - 1, y0)] < i) { next_move.push((beam[b].score, b, x0, y0, !0)); continue; } // 上方向への(評価値の観点で)最適な運び方をDPで計算する for dx in 1..=x0 { let x = x0 - dx; let mut ok = false; for y in y0 - y0.min(dx)..=y0.min(x) { if bs[id(x, y)] < i { continue; } let mut d = (1000000000, 0); let mut prev = (0, !0); if y + dx != y0 { let d2 = dist[id(x + 1, y)]; if d.setmin((d2.0 .0 + 1, d2.0 .1 - bs[id(x, y)])) { prev = (0, d2.1); ok = true; } } if y0 != y { let d2 = dist[id(x + 1, y + 1)]; if d.setmin((d2.0 .0 + 1, d2.0 .1 - bs[id(x, y)])) { prev = (1, d2.1); ok = true; } } let k = if d.0 < 1000000000 { trace2.add(prev.0, prev.1) } else { !0 }; dist[id(x, y)] = (d, k); // 運び方はDPで最適なもの一つに絞るが、運び先に応じてそれぞれ別の遷移とする if d.0 < 1000000000 && (x == 0 || (y == 0 || bs[id(x - 1, y - 1)] < i) && (y == x || bs[id(x - 1, y)] < i)) { next_move.push(( (beam[b].score.0 + dist[id(x, y)].0 .0, beam[b].score.1 + dist[id(x, y)].0 .1), b, x, y, k, )); } } if !ok { break; } } } next_move.sort_by_key(|a| a.0); let mut next = vec![]; let mut set = HashSet::new(); for (score, b, x, y, tid) in next_move { // 多様性確保のため、既に埋まった座標の集合が同じものは1つまでしか選ばないようにする let mut used = beam[b].used.clone(); used.set(id(x, y), true); if !set.insert(used.clone()) { continue; } let (mut x, mut y) = pos[b]; let mut k = beam[b].id; let mut bs = beam[b].bs.clone(); for dy in trace2.get(tid) { k = trace.add(((x, y), (x - 1, y - dy)), k); bs.swap(id(x, y), id(x - 1, y - dy)); x -= 1; y -= dy; } next.push(State { score, bs, id: k, used }); if next.len() == W { break; } } beam = next; } trace.get(beam[0].id) } fn pos(bs: &Vec<i32>, i: i32) -> (usize, usize) { for x in 0..N { for y in 0..=x { if bs[id(x, y)] == i { return (x, y); } } } panic!(); } struct State { bs: Vec<i32>, id: usize, score: (i32, i32), used: BitSet, } // 入出力と得点計算 const N: usize = 30; const N2: usize = N * (N + 1) / 2; fn id(x: usize, y: usize) -> usize { x * (x + 1) / 2 + y } pub type Output = Vec<((usize, usize), (usize, usize))>; #[derive(Clone, Debug)] pub struct Input { pub bs: Vec<i32>, } pub fn read_input() -> Input { input! { bs: [i32; N2] } Input { bs } } pub fn write_output(out: &Output) { println!("{}", out.len()); for &((x1, y1), (x2, y2)) in out { println!("{} {} {} {}", x1, y1, x2, y2); } } // ここからライブラリ pub trait SetMinMax { fn setmin(&mut self, v: Self) -> bool; fn setmax(&mut self, v: Self) -> bool; } impl<T> SetMinMax for T where T: PartialOrd, { fn setmin(&mut self, v: T) -> bool { *self > v && { *self = v; true } } fn setmax(&mut self, v: T) -> bool { *self < v && { *self = v; true } } } #[macro_export] macro_rules! mat { ($($e:expr),*) => { vec![$($e),*] }; ($($e:expr,)*) => { vec![$($e),*] }; ($e:expr; $d:expr) => { vec![$e; $d] }; ($e:expr; $d:expr $(; $ds:expr)+) => { vec![mat![$e $(; $ds)*]; $d] }; } pub 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; } // ローカル環境とジャッジ環境の実行速度差はget_timeで吸収しておくと便利 #[cfg(feature = "local")] { (ms - STIME) * 1.3 } #[cfg(not(feature = "local"))] { ms - STIME } } } struct Trace<T: Copy> { log: Vec<(T, usize)>, } impl<T: Copy> Trace<T> { fn new() -> Self { Trace { log: vec![] } } fn add(&mut self, c: T, p: usize) -> usize { self.log.push((c, p)); self.log.len() - 1 } fn get(&self, mut i: usize) -> Vec<T> { let mut out = vec![]; while i != !0 { out.push(self.log[i].0); i = self.log[i].1; } out.reverse(); out } }
Submission Info
Submission Time | |
---|---|
Task | A - Pyramid Sorting |
User | wata_admin |
Language | Rust (1.42.0) |
Score | 13575560 |
Code Size | 7282 Byte |
Status | AC |
Exec Time | 1821 ms |
Memory | 178068 KiB |
Judge Result
Set Name | test_ALL | ||
---|---|---|---|
Score / Max Score | 13575560 / 15000000 | ||
Status |
|
Set Name | Test Cases |
---|---|
test_ALL | test_0000.txt, test_0001.txt, test_0002.txt, test_0003.txt, test_0004.txt, test_0005.txt, test_0006.txt, test_0007.txt, test_0008.txt, test_0009.txt, test_0010.txt, test_0011.txt, test_0012.txt, test_0013.txt, test_0014.txt, test_0015.txt, test_0016.txt, test_0017.txt, test_0018.txt, test_0019.txt, test_0020.txt, test_0021.txt, test_0022.txt, test_0023.txt, test_0024.txt, test_0025.txt, test_0026.txt, test_0027.txt, test_0028.txt, test_0029.txt, test_0030.txt, test_0031.txt, test_0032.txt, test_0033.txt, test_0034.txt, test_0035.txt, test_0036.txt, test_0037.txt, test_0038.txt, test_0039.txt, test_0040.txt, test_0041.txt, test_0042.txt, test_0043.txt, test_0044.txt, test_0045.txt, test_0046.txt, test_0047.txt, test_0048.txt, test_0049.txt, test_0050.txt, test_0051.txt, test_0052.txt, test_0053.txt, test_0054.txt, test_0055.txt, test_0056.txt, test_0057.txt, test_0058.txt, test_0059.txt, test_0060.txt, test_0061.txt, test_0062.txt, test_0063.txt, test_0064.txt, test_0065.txt, test_0066.txt, test_0067.txt, test_0068.txt, test_0069.txt, test_0070.txt, test_0071.txt, test_0072.txt, test_0073.txt, test_0074.txt, test_0075.txt, test_0076.txt, test_0077.txt, test_0078.txt, test_0079.txt, test_0080.txt, test_0081.txt, test_0082.txt, test_0083.txt, test_0084.txt, test_0085.txt, test_0086.txt, test_0087.txt, test_0088.txt, test_0089.txt, test_0090.txt, test_0091.txt, test_0092.txt, test_0093.txt, test_0094.txt, test_0095.txt, test_0096.txt, test_0097.txt, test_0098.txt, test_0099.txt, test_0100.txt, test_0101.txt, test_0102.txt, test_0103.txt, test_0104.txt, test_0105.txt, test_0106.txt, test_0107.txt, test_0108.txt, test_0109.txt, test_0110.txt, test_0111.txt, test_0112.txt, test_0113.txt, test_0114.txt, test_0115.txt, test_0116.txt, test_0117.txt, test_0118.txt, test_0119.txt, test_0120.txt, test_0121.txt, test_0122.txt, test_0123.txt, test_0124.txt, test_0125.txt, test_0126.txt, test_0127.txt, test_0128.txt, test_0129.txt, test_0130.txt, test_0131.txt, test_0132.txt, test_0133.txt, test_0134.txt, test_0135.txt, test_0136.txt, test_0137.txt, test_0138.txt, test_0139.txt, test_0140.txt, test_0141.txt, test_0142.txt, test_0143.txt, test_0144.txt, test_0145.txt, test_0146.txt, test_0147.txt, test_0148.txt, test_0149.txt |
Case Name | Status | Exec Time | Memory |
---|---|---|---|
test_0000.txt | AC | 1776 ms | 176324 KiB |
test_0001.txt | AC | 1624 ms | 154164 KiB |
test_0002.txt | AC | 1661 ms | 162564 KiB |
test_0003.txt | AC | 1644 ms | 158992 KiB |
test_0004.txt | AC | 1628 ms | 157148 KiB |
test_0005.txt | AC | 1689 ms | 165000 KiB |
test_0006.txt | AC | 1704 ms | 169280 KiB |
test_0007.txt | AC | 1722 ms | 167556 KiB |
test_0008.txt | AC | 1577 ms | 149472 KiB |
test_0009.txt | AC | 1658 ms | 153536 KiB |
test_0010.txt | AC | 1723 ms | 163920 KiB |
test_0011.txt | AC | 1679 ms | 166560 KiB |
test_0012.txt | AC | 1671 ms | 162692 KiB |
test_0013.txt | AC | 1716 ms | 160464 KiB |
test_0014.txt | AC | 1685 ms | 173352 KiB |
test_0015.txt | AC | 1695 ms | 163092 KiB |
test_0016.txt | AC | 1686 ms | 166388 KiB |
test_0017.txt | AC | 1691 ms | 171152 KiB |
test_0018.txt | AC | 1710 ms | 163884 KiB |
test_0019.txt | AC | 1632 ms | 166416 KiB |
test_0020.txt | AC | 1679 ms | 167444 KiB |
test_0021.txt | AC | 1644 ms | 160148 KiB |
test_0022.txt | AC | 1662 ms | 164400 KiB |
test_0023.txt | AC | 1756 ms | 172148 KiB |
test_0024.txt | AC | 1672 ms | 155752 KiB |
test_0025.txt | AC | 1594 ms | 159484 KiB |
test_0026.txt | AC | 1686 ms | 160328 KiB |
test_0027.txt | AC | 1620 ms | 156684 KiB |
test_0028.txt | AC | 1680 ms | 163252 KiB |
test_0029.txt | AC | 1644 ms | 160780 KiB |
test_0030.txt | AC | 1754 ms | 168728 KiB |
test_0031.txt | AC | 1727 ms | 170912 KiB |
test_0032.txt | AC | 1693 ms | 159232 KiB |
test_0033.txt | AC | 1709 ms | 160732 KiB |
test_0034.txt | AC | 1710 ms | 164820 KiB |
test_0035.txt | AC | 1673 ms | 166924 KiB |
test_0036.txt | AC | 1684 ms | 161344 KiB |
test_0037.txt | AC | 1608 ms | 155760 KiB |
test_0038.txt | AC | 1722 ms | 170728 KiB |
test_0039.txt | AC | 1672 ms | 162320 KiB |
test_0040.txt | AC | 1530 ms | 151180 KiB |
test_0041.txt | AC | 1703 ms | 164728 KiB |
test_0042.txt | AC | 1678 ms | 163860 KiB |
test_0043.txt | AC | 1709 ms | 161388 KiB |
test_0044.txt | AC | 1631 ms | 161856 KiB |
test_0045.txt | AC | 1675 ms | 166708 KiB |
test_0046.txt | AC | 1660 ms | 160088 KiB |
test_0047.txt | AC | 1798 ms | 170172 KiB |
test_0048.txt | AC | 1694 ms | 160032 KiB |
test_0049.txt | AC | 1689 ms | 162640 KiB |
test_0050.txt | AC | 1729 ms | 169260 KiB |
test_0051.txt | AC | 1703 ms | 156504 KiB |
test_0052.txt | AC | 1625 ms | 158304 KiB |
test_0053.txt | AC | 1651 ms | 159184 KiB |
test_0054.txt | AC | 1720 ms | 170184 KiB |
test_0055.txt | AC | 1701 ms | 166116 KiB |
test_0056.txt | AC | 1728 ms | 164108 KiB |
test_0057.txt | AC | 1786 ms | 171400 KiB |
test_0058.txt | AC | 1821 ms | 171840 KiB |
test_0059.txt | AC | 1744 ms | 162912 KiB |
test_0060.txt | AC | 1744 ms | 168748 KiB |
test_0061.txt | AC | 1751 ms | 167328 KiB |
test_0062.txt | AC | 1704 ms | 163084 KiB |
test_0063.txt | AC | 1682 ms | 164624 KiB |
test_0064.txt | AC | 1655 ms | 161004 KiB |
test_0065.txt | AC | 1715 ms | 164100 KiB |
test_0066.txt | AC | 1750 ms | 166604 KiB |
test_0067.txt | AC | 1734 ms | 168212 KiB |
test_0068.txt | AC | 1698 ms | 161668 KiB |
test_0069.txt | AC | 1675 ms | 163796 KiB |
test_0070.txt | AC | 1756 ms | 164620 KiB |
test_0071.txt | AC | 1663 ms | 154672 KiB |
test_0072.txt | AC | 1704 ms | 162188 KiB |
test_0073.txt | AC | 1702 ms | 163200 KiB |
test_0074.txt | AC | 1692 ms | 157220 KiB |
test_0075.txt | AC | 1668 ms | 162964 KiB |
test_0076.txt | AC | 1790 ms | 168644 KiB |
test_0077.txt | AC | 1659 ms | 160716 KiB |
test_0078.txt | AC | 1699 ms | 157380 KiB |
test_0079.txt | AC | 1716 ms | 157372 KiB |
test_0080.txt | AC | 1731 ms | 166548 KiB |
test_0081.txt | AC | 1709 ms | 163528 KiB |
test_0082.txt | AC | 1634 ms | 153960 KiB |
test_0083.txt | AC | 1669 ms | 163928 KiB |
test_0084.txt | AC | 1701 ms | 165024 KiB |
test_0085.txt | AC | 1677 ms | 159980 KiB |
test_0086.txt | AC | 1731 ms | 167008 KiB |
test_0087.txt | AC | 1725 ms | 167568 KiB |
test_0088.txt | AC | 1710 ms | 168532 KiB |
test_0089.txt | AC | 1723 ms | 165820 KiB |
test_0090.txt | AC | 1706 ms | 166108 KiB |
test_0091.txt | AC | 1659 ms | 164028 KiB |
test_0092.txt | AC | 1658 ms | 163436 KiB |
test_0093.txt | AC | 1617 ms | 164108 KiB |
test_0094.txt | AC | 1684 ms | 169484 KiB |
test_0095.txt | AC | 1607 ms | 152812 KiB |
test_0096.txt | AC | 1708 ms | 170036 KiB |
test_0097.txt | AC | 1688 ms | 162444 KiB |
test_0098.txt | AC | 1666 ms | 164056 KiB |
test_0099.txt | AC | 1714 ms | 163760 KiB |
test_0100.txt | AC | 1672 ms | 164292 KiB |
test_0101.txt | AC | 1689 ms | 162708 KiB |
test_0102.txt | AC | 1673 ms | 167548 KiB |
test_0103.txt | AC | 1731 ms | 175608 KiB |
test_0104.txt | AC | 1637 ms | 158396 KiB |
test_0105.txt | AC | 1706 ms | 166588 KiB |
test_0106.txt | AC | 1750 ms | 172420 KiB |
test_0107.txt | AC | 1713 ms | 169040 KiB |
test_0108.txt | AC | 1689 ms | 162308 KiB |
test_0109.txt | AC | 1651 ms | 167232 KiB |
test_0110.txt | AC | 1700 ms | 165716 KiB |
test_0111.txt | AC | 1766 ms | 173432 KiB |
test_0112.txt | AC | 1714 ms | 165700 KiB |
test_0113.txt | AC | 1669 ms | 162104 KiB |
test_0114.txt | AC | 1794 ms | 178068 KiB |
test_0115.txt | AC | 1658 ms | 158800 KiB |
test_0116.txt | AC | 1719 ms | 159444 KiB |
test_0117.txt | AC | 1663 ms | 163980 KiB |
test_0118.txt | AC | 1690 ms | 163816 KiB |
test_0119.txt | AC | 1686 ms | 163844 KiB |
test_0120.txt | AC | 1744 ms | 168640 KiB |
test_0121.txt | AC | 1728 ms | 165580 KiB |
test_0122.txt | AC | 1689 ms | 159828 KiB |
test_0123.txt | AC | 1681 ms | 163004 KiB |
test_0124.txt | AC | 1692 ms | 165208 KiB |
test_0125.txt | AC | 1739 ms | 170036 KiB |
test_0126.txt | AC | 1667 ms | 160244 KiB |
test_0127.txt | AC | 1658 ms | 163320 KiB |
test_0128.txt | AC | 1657 ms | 162080 KiB |
test_0129.txt | AC | 1719 ms | 169860 KiB |
test_0130.txt | AC | 1726 ms | 160956 KiB |
test_0131.txt | AC | 1640 ms | 159960 KiB |
test_0132.txt | AC | 1730 ms | 173772 KiB |
test_0133.txt | AC | 1670 ms | 162760 KiB |
test_0134.txt | AC | 1687 ms | 166512 KiB |
test_0135.txt | AC | 1708 ms | 165264 KiB |
test_0136.txt | AC | 1627 ms | 157156 KiB |
test_0137.txt | AC | 1735 ms | 170420 KiB |
test_0138.txt | AC | 1698 ms | 163956 KiB |
test_0139.txt | AC | 1666 ms | 161672 KiB |
test_0140.txt | AC | 1651 ms | 157992 KiB |
test_0141.txt | AC | 1774 ms | 172468 KiB |
test_0142.txt | AC | 1711 ms | 163404 KiB |
test_0143.txt | AC | 1721 ms | 163052 KiB |
test_0144.txt | AC | 1757 ms | 168344 KiB |
test_0145.txt | AC | 1598 ms | 161448 KiB |
test_0146.txt | AC | 1750 ms | 170072 KiB |
test_0147.txt | AC | 1732 ms | 163620 KiB |
test_0148.txt | AC | 1703 ms | 169532 KiB |
test_0149.txt | AC | 1576 ms | 150372 KiB |