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 |