https://atcoder.jp/contests/abc258/tasks/abc258_b
全てのマスから全ての方向を計算して、そこまでのうち最大のものだけ残して、その方向に1歩進めるというのを繰り返します。
あまりうまくIteratorが使えずに、結局collectしてVecにしています。
// Number Box #![allow(non_snake_case)] use std::ops::Add; use std::ops::Mul; //////////////////// library //////////////////// fn read<T: std::str::FromStr>() -> T { let mut line = String::new(); std::io::stdin().read_line(&mut line).ok(); line.trim().parse().ok().unwrap() } fn read_matrix() -> Vec<Vec<i32>> { fn read_row() -> Vec<i32> { read::<String>().chars().map(|c| (c as i32) - 48).collect() } let N: i32 = read(); (0..N).map(|_| read_row()).collect() } fn modulo(n: i32, d: i32) -> i32 { let r = n % d; if r >= 0 { r } else { r + d } } //////////////////// Point //////////////////// #[derive(Clone, Copy)] struct Point { x: i32, y: i32, } impl Add for Point { type Output = Self; fn add(self, other: Self) -> Self { Self { x: self.x + other.x, y: self.y + other.y } } } impl Mul<i32> for Point { type Output = Self; fn mul(self, c: i32) -> Self { Self { x: self.x * c, y: self.y * c } } } //////////////////// Box //////////////////// struct Box { A: Vec<Vec<i32>> } impl Box { fn value(&self, pt: Point) -> i64 { let pt2 = self.mod_point(pt); self.A[pt2.x as usize][pt2.y as usize] as i64 } fn mod_point(&self, pt: Point) -> Point { let d = self.A.len() as i32; Point { x: modulo(pt.x, d), y: modulo(pt.y, d) } } fn make_dirs() -> Vec<Point> { (0..9).filter(|&i| i != 4). map(|i| Point { x: i/3-1, y: i%3-1 }).collect() } } //////////////////// ValueSet //////////////////// #[derive(Clone, Copy)] struct ValueSet { pt0: Point, dir: Point, i: i32, n: i64 } impl ValueSet { fn next(&self, b: &Box) -> ValueSet { let pt = self.next_point(); let i = self.i + 1; let n = 10 * self.n + b.value(pt); ValueSet { pt0: self.pt0, dir: self.dir, i, n } } fn next_point(&self) -> Point { self.pt0 + self.dir * (self.i + 1) } fn create(i: usize, dirs: &Vec<Point>, N: usize) -> ValueSet { let M = N as i32; let L = dirs.len(); let r = i % L; let q = (i / L) as i32; let pt = Point { x: q / M, y: q % M }; ValueSet { pt0: pt, dir: dirs[r], i: -1, n: 0 } } } //////////////////// process //////////////////// fn max_elements(w: &Vec<ValueSet>) -> Vec<ValueSet> { let mut v = Vec::<ValueSet>::new(); if w.len() == 0 { return v } v.push(w[0]); for i in 1..w.len() { let e = w[i]; if e.n > v[0].n { v.clear(); v.push(e) } else if e.n == v[0].n { v.push(e) } } return v } fn main() { let A = read_matrix(); let N = A.len(); let b = Box { A }; let dirs = Box::make_dirs(); let mut v: Vec<ValueSet> = (0..(N*N*8)). map(|i| ValueSet::create(i, &dirs, N)). collect(); for _ in 0..N { let w = max_elements(&v); v = w.iter().map(|&s| s.next(&b)).collect(); } match v.iter().next() { Some(x) => println!("{}", x.n), None => () } }