QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#836246 | #9926. Flipping Paths | ucup-team296# | WA | 0ms | 2148kb | Rust | 31.7kb | 2024-12-28 17:37:05 | 2024-12-28 17:37:05 |
Judging History
answer
// https://contest.ucup.ac/contest/1885/problem/9926
use crate::algo_lib::collections::md_arr::arr2d::{Arr2d, Arr2dRead};
use crate::algo_lib::io::input::Input;
use crate::algo_lib::io::output::Output;
use crate::algo_lib::misc::test_type::TaskType;
use crate::algo_lib::misc::test_type::TestType;
use crate::algo_lib::string::str::Str;
type PreCalc = ();
fn solve(input: &mut Input, out: &mut Output, _test_case: usize, _data: &mut PreCalc) {
let n = input.read_size();
let m = input.read_size();
let c = input.read_char_table(n, m);
for &z in b"WB" {
let mut c = c.clone();
fn path(
c: &mut Arr2d<u8>,
x: usize,
y: usize,
z: u8,
) -> ((usize, usize), (usize, usize), Str) {
assert_ne!(c[(x, y)], z);
let mut xx = x;
let mut yy = y;
let mut path = Str::new();
loop {
c[(xx, yy)] = z;
if xx + 1 < c.d1() && c[(xx + 1, yy)] != z {
xx += 1;
path.push(b'D');
} else if yy + 1 < c.d2() && c[(xx, yy + 1)] != z {
yy += 1;
path.push(b'R');
} else {
break;
}
}
((x, y), (xx, yy), path)
}
let mut paths = Arr2d::new(n, m, Vec::new());
if c[(0, 0)] != z {
let (_, (xx, yy), path) = path(&mut c, 0, 0, z);
if xx != c.d1() - 1 || yy != c.d2() - 1 {
continue;
}
paths[(xx, yy)].push(path);
}
let mut good = true;
'outer: for i in 0..m {
for j in 0..n {
if c[(j, i)] != z {
if j == 0 || i == m - 1 || c[(j - 1, i + 1)] == z {
good = false;
break 'outer;
}
let (_, (xx, yy), path1) = path(&mut c, j, i, z);
let (_, (xx2, yy2), path2) = path(&mut c, j - 1, i + 1, z);
if xx != xx2 + 1 || yy + 1 != yy2 {
good = false;
break 'outer;
}
let mut sx = 0;
let mut sy = 0;
let mut prefix1 = Str::new();
let mut prefix2 = Str::new();
'inner: for x in (0..j).rev() {
for y in 0..=i {
if !paths[(x, y)].is_empty() {
sx = x;
sy = y;
prefix1 = paths[(x, y)].pop().unwrap();
prefix2 = paths[(x, y)].pop().unwrap();
break 'inner;
}
}
}
for _ in sx..j - 1 {
prefix1.push(b'D');
prefix2.push(b'D');
}
for _ in sy..i {
prefix1.push(b'R');
prefix2.push(b'R');
}
let mut p1 = prefix1;
p1.push(b'D');
p1 += &path1;
p1.push(b'R');
let mut p2 = prefix2;
p2.push(b'R');
p2 += &path2;
p2.push(b'D');
paths[(xx, yy + 1)].push(p1);
paths[(xx, yy + 1)].push(p2);
}
}
}
if !good {
continue;
}
let mut ans = Vec::new();
for i in 0..n {
for j in 0..m {
for mut path in paths[(i, j)].drain(..) {
for _ in i + 1..n {
path.push(b'D');
}
for _ in j + 1..m {
path.push(b'R');
}
ans.push(path);
}
}
}
out.print_line(true);
out.print_line(ans.len());
out.print_per_line(&ans);
return;
}
out.print_line(false);
}
pub static TEST_TYPE: TestType = TestType::MultiNumber;
pub static TASK_TYPE: TaskType = TaskType::Classic;
pub(crate) fn run(mut input: Input, mut output: Output) -> bool {
let mut pre_calc = ();
match TEST_TYPE {
TestType::Single => solve(&mut input, &mut output, 1, &mut pre_calc),
TestType::MultiNumber => {
let t = input.read();
for i in 1..=t {
solve(&mut input, &mut output, i, &mut pre_calc);
}
}
TestType::MultiEof => {
let mut i = 1;
while input.peek().is_some() {
solve(&mut input, &mut output, i, &mut pre_calc);
i += 1;
}
}
}
output.flush();
match TASK_TYPE {
TaskType::Classic => input.is_empty(),
TaskType::Interactive => true,
}
}
fn main() {
let mut sin = std::io::stdin();
let input = crate::algo_lib::io::input::Input::new(&mut sin);
let mut stdout = std::io::stdout();
let output = crate::algo_lib::io::output::Output::new(&mut stdout);
run(input, output);
}
pub mod algo_lib {
pub mod collections {
pub mod md_arr {
pub mod arr2d {
use crate::algo_lib::collections::slice_ext::legacy_fill::LegacyFill;
use crate::algo_lib::io::input::{Input, Readable};
use crate::algo_lib::io::output::{Output, Writable};
use std::iter::{Skip, StepBy, Take};
use std::mem::MaybeUninit;
use std::ops::{Index, IndexMut, Range};
use std::slice::{Iter, IterMut};
use std::vec::IntoIter;
#[derive(Clone, Eq, PartialEq, Default, Debug, Hash)]
pub struct Arr2d<T> {
d1: usize,
d2: usize,
data: Vec<T>,
}
impl<T: Clone> Arr2d<T> {
pub fn new(d1: usize, d2: usize, value: T) -> Self {
Self {
d1,
d2,
data: vec![value; d1 * d2],
}
}
}
impl<T> Arr2d<T> {
pub fn gen<F>(d1: usize, d2: usize, mut gen: F) -> Self
where
F: FnMut(usize, usize) -> T,
{
let mut data = Vec::with_capacity(d1 * d2);
for i in 0usize..d1 {
for j in 0usize..d2 {
data.push(gen(i, j));
}
}
Self { d1, d2, data }
}
pub fn d1(&self) -> usize {
self.d1
}
pub fn d2(&self) -> usize {
self.d2
}
pub fn iter(&self) -> Iter<'_, T> {
self.data.iter()
}
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
self.data.iter_mut()
}
pub fn row(&self, row: usize) -> Take<Skip<Iter<'_, T>>> {
assert!(row < self.d1);
self.data.iter().skip(row * self.d2).take(self.d2)
}
pub fn row_mut(&mut self, row: usize) -> Take<Skip<IterMut<'_, T>>> {
assert!(row < self.d1);
self.data.iter_mut().skip(row * self.d2).take(self.d2)
}
pub fn col(&self, col: usize) -> StepBy<Skip<Iter<'_, T>>> {
assert!(col < self.d2);
self.data.iter().skip(col).step_by(self.d2)
}
pub fn col_mut(&mut self, col: usize) -> StepBy<Skip<IterMut<'_, T>>> {
assert!(col < self.d2);
self.data.iter_mut().skip(col).step_by(self.d2)
}
pub fn swap(&mut self, r1: usize, c1: usize, r2: usize, c2: usize) {
assert!(c1 < self.d2);
assert!(c2 < self.d2);
self.data.swap(r1 * self.d2 + c1, r2 * self.d2 + c2);
}
pub fn rows(&self) -> Range<usize> {
0..self.d1
}
pub fn cols(&self) -> Range<usize> {
0..self.d2
}
pub fn swap_rows(&mut self, r1: usize, r2: usize) {
if r1 == r2 {
assert!(r1 < self.d1);
return;
}
let (r1, r2) = (r1.min(r2), r1.max(r2));
let (head, tail) = self.data.split_at_mut(r2 * self.d2);
head[r1 * self.d2..(r1 + 1) * self.d2].swap_with_slice(&mut tail[..self.d2]);
}
pub fn rotate_clockwise(self) -> Self {
unsafe {
let d1 = self.d1;
let d2 = self.d2;
let mut res = MaybeUninit::new(Vec::with_capacity(d1 * d2));
(*res.as_mut_ptr()).set_len(d1 * d2);
for (id, element) in self.into_iter().enumerate() {
let (i, j) = (id / d2, id % d2);
let ptr: *mut T = (*res.as_mut_ptr()).as_mut_ptr();
ptr.add(j * d1 + d1 - i - 1).write(element);
}
Self {
d1: d2,
d2: d1,
data: res.assume_init(),
}
}
}
pub fn rotate_counterclockwise(self) -> Self {
unsafe {
let d1 = self.d1;
let d2 = self.d2;
let mut res = MaybeUninit::new(Vec::with_capacity(d1 * d2));
(*res.as_mut_ptr()).set_len(d1 * d2);
for (id, element) in self.into_iter().enumerate() {
let (i, j) = (id / d2, id % d2);
let ptr: *mut T = (*res.as_mut_ptr()).as_mut_ptr();
ptr.add((d2 - j - 1) * d1 + i).write(element);
}
Self {
d1: d2,
d2: d1,
data: res.assume_init(),
}
}
}
pub fn transpose(self) -> Self {
unsafe {
let d1 = self.d1;
let d2 = self.d2;
let mut res = MaybeUninit::new(Vec::with_capacity(d1 * d2));
(*res.as_mut_ptr()).set_len(d1 * d2);
for (id, element) in self.into_iter().enumerate() {
let (i, j) = (id / d2, id % d2);
let ptr: *mut T = (*res.as_mut_ptr()).as_mut_ptr();
ptr.add(j * d1 + i).write(element);
}
Self {
d1: d2,
d2: d1,
data: res.assume_init(),
}
}
}
}
impl<T: Clone> Arr2d<T> {
pub fn fill(&mut self, elem: T) {
self.data.legacy_fill(elem);
}
}
impl<T> Index<(usize, usize)> for Arr2d<T> {
type Output = T;
fn index(&self, (row, col): (usize, usize)) -> &Self::Output {
assert!(col < self.d2);
&self.data[self.d2 * row + col]
}
}
impl<T> Index<usize> for Arr2d<T> {
type Output = [T];
fn index(&self, index: usize) -> &Self::Output {
&self.data[self.d2 * index..self.d2 * (index + 1)]
}
}
impl<T> IndexMut<(usize, usize)> for Arr2d<T> {
fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut T {
assert!(col < self.d2);
&mut self.data[self.d2 * row + col]
}
}
impl<T> IndexMut<usize> for Arr2d<T> {
fn index_mut(&mut self, index: usize) -> &mut [T] {
&mut self.data[self.d2 * index..self.d2 * (index + 1)]
}
}
impl<T> AsRef<Vec<T>> for Arr2d<T> {
fn as_ref(&self) -> &Vec<T> {
&self.data
}
}
impl<T> AsMut<Vec<T>> for Arr2d<T> {
fn as_mut(&mut self) -> &mut Vec<T> {
&mut self.data
}
}
impl<T: Writable> Writable for Arr2d<T> {
fn write(&self, output: &mut Output) {
let mut at = 0usize;
for i in 0usize..self.d1 {
if i != 0 {
output.put(b'\n');
}
for j in 0usize..self.d2 {
if j != 0 {
output.put(output.separator());
}
self.data[at].write(output);
at += 1;
}
}
}
}
impl<T> IntoIterator for Arr2d<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.data.into_iter()
}
}
impl<'a, T> IntoIterator for &'a Arr2d<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub trait Arr2dRead {
fn read_table<T: Readable>(&mut self, d1: usize, d2: usize) -> Arr2d<T>;
fn read_int_table(&mut self, d1: usize, d2: usize) -> Arr2d<i32>;
fn read_long_table(&mut self, d1: usize, d2: usize) -> Arr2d<i64>;
fn read_size_table(&mut self, d1: usize, d2: usize) -> Arr2d<usize>;
fn read_char_table(&mut self, d1: usize, d2: usize) -> Arr2d<u8>;
}
impl Arr2dRead for Input<'_> {
fn read_table<T: Readable>(&mut self, d1: usize, d2: usize) -> Arr2d<T> {
Arr2d::gen(d1, d2, |_, _| self.read())
}
fn read_int_table(&mut self, d1: usize, d2: usize) -> Arr2d<i32> {
self.read_table(d1, d2)
}
fn read_long_table(&mut self, d1: usize, d2: usize) -> Arr2d<i64> {
self.read_table(d1, d2)
}
fn read_size_table(&mut self, d1: usize, d2: usize) -> Arr2d<usize> {
self.read_table(d1, d2)
}
fn read_char_table(&mut self, d1: usize, d2: usize) -> Arr2d<u8> {
self.read_table(d1, d2)
}
}
pub trait Arr2dCharWrite {
fn print_table(&mut self, table: &Arr2d<u8>);
}
impl Arr2dCharWrite for Output<'_> {
fn print_table(&mut self, table: &Arr2d<u8>) {
let mut at = 0usize;
for _ in 0..table.d1 {
for _ in 0..table.d2 {
self.put(table.data[at]);
at += 1;
}
self.put(b'\n');
}
self.maybe_flush();
}
}
impl<T: Readable> Readable for Arr2d<T> {
fn read(input: &mut Input) -> Self {
let d1 = input.read();
let d2 = input.read();
input.read_table(d1, d2)
}
}
}
}
pub mod slice_ext {
pub mod legacy_fill {
pub trait LegacyFill<T> {
fn legacy_fill(&mut self, val: T);
}
impl<T: Clone> LegacyFill<T> for [T] {
fn legacy_fill(&mut self, val: T) {
for el in self.iter_mut() {
*el = val.clone();
}
}
}
}
}
pub mod vec_ext {
pub mod default {
pub fn default_vec<T: Default>(len: usize) -> Vec<T> {
let mut v = Vec::with_capacity(len);
for _ in 0..len {
v.push(T::default());
}
v
}
}
}
}
pub mod io {
pub mod input {
use crate::algo_lib::collections::vec_ext::default::default_vec;
use std::io::Read;
use std::mem::MaybeUninit;
pub struct Input<'s> {
input: &'s mut (dyn Read + Send),
buf: Vec<u8>,
at: usize,
buf_read: usize,
eol: bool,
}
macro_rules! read_impl {
($t:ty, $read_name:ident, $read_vec_name:ident) => {
pub fn $read_name (& mut self) -> $t { self.read() } pub fn $read_vec_name (& mut
self, len : usize) -> Vec <$t > { self.read_vec(len) }
};
($t:ty, $read_name:ident, $read_vec_name:ident, $read_pair_vec_name:ident) => {
read_impl!($t, $read_name, $read_vec_name); pub fn $read_pair_vec_name (& mut
self, len : usize) -> Vec < ($t, $t) > { self.read_vec(len) }
};
}
impl<'s> Input<'s> {
const DEFAULT_BUF_SIZE: usize = 4096;
pub fn new(input: &'s mut (dyn Read + Send)) -> Self {
Self {
input,
buf: default_vec(Self::DEFAULT_BUF_SIZE),
at: 0,
buf_read: 0,
eol: true,
}
}
pub fn new_with_size(input: &'s mut (dyn Read + Send), buf_size: usize) -> Self {
Self {
input,
buf: default_vec(buf_size),
at: 0,
buf_read: 0,
eol: true,
}
}
pub fn get(&mut self) -> Option<u8> {
if self.refill_buffer() {
let res = self.buf[self.at];
self.at += 1;
if res == b'\r' {
self.eol = true;
if self.refill_buffer() && self.buf[self.at] == b'\n' {
self.at += 1;
}
return Some(b'\n');
}
self.eol = res == b'\n';
Some(res)
} else {
None
}
}
pub fn peek(&mut self) -> Option<u8> {
if self.refill_buffer() {
let res = self.buf[self.at];
Some(if res == b'\r' { b'\n' } else { res })
} else {
None
}
}
pub fn skip_whitespace(&mut self) {
while let Some(b) = self.peek() {
if !b.is_ascii_whitespace() {
return;
}
self.get();
}
}
pub fn next_token(&mut self) -> Option<Vec<u8>> {
self.skip_whitespace();
let mut res = Vec::new();
while let Some(c) = self.get() {
if c.is_ascii_whitespace() {
break;
}
res.push(c);
}
if res.is_empty() { None } else { Some(res) }
}
pub fn is_exhausted(&mut self) -> bool {
self.peek().is_none()
}
pub fn is_empty(&mut self) -> bool {
self.skip_whitespace();
self.is_exhausted()
}
pub fn read<T: Readable>(&mut self) -> T {
T::read(self)
}
pub fn read_vec<T: Readable>(&mut self, size: usize) -> Vec<T> {
let mut res = Vec::with_capacity(size);
for _ in 0..size {
res.push(self.read());
}
res
}
pub fn read_char(&mut self) -> u8 {
self.skip_whitespace();
self.get().unwrap()
}
read_impl!(u32, read_unsigned, read_unsigned_vec);
read_impl!(u64, read_u64, read_u64_vec);
read_impl!(usize, read_size, read_size_vec, read_size_pair_vec);
read_impl!(i32, read_int, read_int_vec, read_int_pair_vec);
read_impl!(i64, read_long, read_long_vec, read_long_pair_vec);
read_impl!(i128, read_i128, read_i128_vec);
fn refill_buffer(&mut self) -> bool {
if self.at == self.buf_read {
self.at = 0;
self.buf_read = self.input.read(&mut self.buf).unwrap();
self.buf_read != 0
} else {
true
}
}
pub fn is_eol(&self) -> bool {
self.eol
}
}
pub trait Readable {
fn read(input: &mut Input) -> Self;
}
impl Readable for u8 {
fn read(input: &mut Input) -> Self {
input.read_char()
}
}
impl<T: Readable> Readable for Vec<T> {
fn read(input: &mut Input) -> Self {
let size = input.read();
input.read_vec(size)
}
}
impl<T: Readable, const SIZE: usize> Readable for [T; SIZE] {
fn read(input: &mut Input) -> Self {
unsafe {
let mut res = MaybeUninit::<[T; SIZE]>::uninit();
for i in 0..SIZE {
let ptr: *mut T = (*res.as_mut_ptr()).as_mut_ptr();
ptr.add(i).write(input.read::<T>());
}
res.assume_init()
}
}
}
macro_rules! read_integer {
($($t:ident)+) => {
$(impl Readable for $t { fn read(input : & mut Input) -> Self { input
.skip_whitespace(); let mut c = input.get().unwrap(); let sgn = match c { b'-' =>
{ c = input.get().unwrap(); true } b'+' => { c = input.get().unwrap(); false } _
=> false, }; let mut res = 0; loop { assert!(c.is_ascii_digit()); res *= 10; let
d = (c - b'0') as $t; if sgn { res -= d; } else { res += d; } match input.get() {
None => break, Some(ch) => { if ch.is_ascii_whitespace() { break; } else { c =
ch; } } } } res } })+
};
}
read_integer!(i8 i16 i32 i64 i128 isize u16 u32 u64 u128 usize);
macro_rules! tuple_readable {
($($name:ident)+) => {
impl <$($name : Readable),+> Readable for ($($name,)+) { fn read(input : & mut
Input) -> Self { ($($name ::read(input),)+) } }
};
}
tuple_readable! {
T
}
tuple_readable! {
T U
}
tuple_readable! {
T U V
}
tuple_readable! {
T U V X
}
tuple_readable! {
T U V X Y
}
tuple_readable! {
T U V X Y Z
}
tuple_readable! {
T U V X Y Z A
}
tuple_readable! {
T U V X Y Z A B
}
tuple_readable! {
T U V X Y Z A B C
}
tuple_readable! {
T U V X Y Z A B C D
}
tuple_readable! {
T U V X Y Z A B C D E
}
tuple_readable! {
T U V X Y Z A B C D E F
}
impl Read for Input<'_> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
if self.at == self.buf_read {
self.input.read(buf)
} else {
let mut i = 0;
while i < buf.len() && self.at < self.buf_read {
buf[i] = self.buf[self.at];
i += 1;
self.at += 1;
}
Ok(i)
}
}
}
}
pub mod output {
use crate::algo_lib::collections::vec_ext::default::default_vec;
use std::cmp::Reverse;
use std::io::{stderr, Stderr, Write};
#[derive(Copy, Clone)]
pub enum BoolOutput {
YesNo,
YesNoCaps,
PossibleImpossible,
Custom(&'static str, &'static str),
}
impl BoolOutput {
pub fn output(&self, output: &mut Output, val: bool) {
(if val { self.yes() } else { self.no() }).write(output);
}
fn yes(&self) -> &str {
match self {
BoolOutput::YesNo => "Yes",
BoolOutput::YesNoCaps => "YES",
BoolOutput::PossibleImpossible => "Possible",
BoolOutput::Custom(yes, _) => yes,
}
}
fn no(&self) -> &str {
match self {
BoolOutput::YesNo => "No",
BoolOutput::YesNoCaps => "NO",
BoolOutput::PossibleImpossible => "Impossible",
BoolOutput::Custom(_, no) => no,
}
}
}
pub struct Output<'s> {
output: &'s mut dyn Write,
buf: Vec<u8>,
at: usize,
auto_flush: bool,
bool_output: BoolOutput,
precision: Option<usize>,
separator: u8,
}
impl<'s> Output<'s> {
const DEFAULT_BUF_SIZE: usize = 4096;
pub fn new(output: &'s mut dyn Write) -> Self {
Self {
output,
buf: default_vec(Self::DEFAULT_BUF_SIZE),
at: 0,
auto_flush: false,
bool_output: BoolOutput::YesNoCaps,
precision: None,
separator: b' ',
}
}
pub fn new_with_auto_flush(output: &'s mut dyn Write) -> Self {
Self {
output,
buf: default_vec(Self::DEFAULT_BUF_SIZE),
at: 0,
auto_flush: true,
bool_output: BoolOutput::YesNoCaps,
precision: None,
separator: b' ',
}
}
pub fn flush(&mut self) {
if self.at != 0 {
self.output.write_all(&self.buf[..self.at]).unwrap();
self.output.flush().unwrap();
self.at = 0;
}
}
pub fn print<T: Writable>(&mut self, s: T) {
s.write(self);
self.maybe_flush();
}
pub fn print_line<T: Writable>(&mut self, s: T) {
self.print(s);
self.put(b'\n');
self.maybe_flush();
}
pub fn put(&mut self, b: u8) {
self.buf[self.at] = b;
self.at += 1;
if self.at == self.buf.len() {
self.flush();
}
}
pub fn maybe_flush(&mut self) {
if self.auto_flush {
self.flush();
}
}
pub fn print_per_line<T: Writable>(&mut self, arg: &[T]) {
self.print_per_line_iter(arg.iter());
}
pub fn print_iter<T: Writable, I: Iterator<Item = T>>(&mut self, iter: I) {
let mut first = true;
for e in iter {
if first {
first = false;
} else {
self.put(self.separator);
}
e.write(self);
}
}
pub fn print_line_iter<T: Writable, I: Iterator<Item = T>>(&mut self, iter: I) {
self.print_iter(iter);
self.put(b'\n');
}
pub fn print_per_line_iter<T: Writable, I: Iterator<Item = T>>(&mut self, iter: I) {
for e in iter {
e.write(self);
self.put(b'\n');
}
}
pub fn set_bool_output(&mut self, bool_output: BoolOutput) {
self.bool_output = bool_output;
}
pub fn set_precision(&mut self, precision: usize) {
self.precision = Some(precision);
}
pub fn reset_precision(&mut self) {
self.precision = None;
}
pub fn get_precision(&self) -> Option<usize> {
self.precision
}
pub fn separator(&self) -> u8 {
self.separator
}
pub fn set_separator(&mut self, separator: u8) {
self.separator = separator;
}
}
impl Write for Output<'_> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let mut start = 0usize;
let mut rem = buf.len();
while rem > 0 {
let len = (self.buf.len() - self.at).min(rem);
self.buf[self.at..self.at + len].copy_from_slice(&buf[start..start + len]);
self.at += len;
if self.at == self.buf.len() {
self.flush();
}
start += len;
rem -= len;
}
self.maybe_flush();
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
self.flush();
Ok(())
}
}
pub trait Writable {
fn write(&self, output: &mut Output);
}
impl Writable for &str {
fn write(&self, output: &mut Output) {
output.write_all(self.as_bytes()).unwrap();
}
}
impl Writable for String {
fn write(&self, output: &mut Output) {
output.write_all(self.as_bytes()).unwrap();
}
}
impl Writable for char {
fn write(&self, output: &mut Output) {
output.put(*self as u8);
}
}
impl Writable for u8 {
fn write(&self, output: &mut Output) {
output.put(*self);
}
}
impl<T: Writable> Writable for [T] {
fn write(&self, output: &mut Output) {
output.print_iter(self.iter());
}
}
impl<T: Writable, const N: usize> Writable for [T; N] {
fn write(&self, output: &mut Output) {
output.print_iter(self.iter());
}
}
impl<T: Writable + ?Sized> Writable for &T {
fn write(&self, output: &mut Output) {
T::write(self, output)
}
}
impl<T: Writable> Writable for Vec<T> {
fn write(&self, output: &mut Output) {
self.as_slice().write(output);
}
}
impl Writable for () {
fn write(&self, _output: &mut Output) {}
}
macro_rules! write_to_string {
($($t:ident)+) => {
$(impl Writable for $t { fn write(& self, output : & mut Output) { self
.to_string().write(output); } })+
};
}
write_to_string!(u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);
macro_rules! tuple_writable {
($name0:ident $($name:ident : $id:tt)*) => {
impl <$name0 : Writable, $($name : Writable,)*> Writable for ($name0, $($name,)*)
{ fn write(& self, out : & mut Output) { self.0.write(out); $(out.put(out
.separator); self.$id .write(out);)* } }
};
}
tuple_writable! {
T
}
tuple_writable! {
T U : 1
}
tuple_writable! {
T U : 1 V : 2
}
tuple_writable! {
T U : 1 V : 2 X : 3
}
tuple_writable! {
T U : 1 V : 2 X : 3 Y : 4
}
tuple_writable! {
T U : 1 V : 2 X : 3 Y : 4 Z : 5
}
tuple_writable! {
T U : 1 V : 2 X : 3 Y : 4 Z : 5 A : 6
}
tuple_writable! {
T U : 1 V : 2 X : 3 Y : 4 Z : 5 A : 6 B : 7
}
tuple_writable! {
T U : 1 V : 2 X : 3 Y : 4 Z : 5 A : 6 B : 7 C : 8
}
impl<T: Writable> Writable for Option<T> {
fn write(&self, output: &mut Output) {
match self {
None => (-1).write(output),
Some(t) => t.write(output),
}
}
}
impl Writable for bool {
fn write(&self, output: &mut Output) {
let bool_output = output.bool_output;
bool_output.output(output, *self)
}
}
impl<T: Writable> Writable for Reverse<T> {
fn write(&self, output: &mut Output) {
self.0.write(output);
}
}
static mut ERR: Option<Stderr> = None;
pub fn err() -> Output<'static> {
unsafe {
if ERR.is_none() {
ERR = Some(stderr());
}
Output::new_with_auto_flush(ERR.as_mut().unwrap())
}
}
}
}
pub mod misc {
pub mod test_type {
pub enum TestType {
Single,
MultiNumber,
MultiEof,
}
pub enum TaskType {
Classic,
Interactive,
}
}
}
pub mod string {
pub mod str {
use crate::algo_lib::io::input::{Input, Readable};
use crate::algo_lib::io::output::{Output, Writable};
use std::fmt::Display;
use std::io::Write;
use std::iter::FromIterator;
use std::ops::{AddAssign, Deref, DerefMut};
use std::str::from_utf8_unchecked;
use std::vec::IntoIter;
#[derive(Eq, PartialEq, Hash, PartialOrd, Ord, Clone, Default)]
pub struct Str(Vec<u8>);
impl Str {
pub fn new() -> Self {
Self(Vec::new())
}
pub fn unwrap(self) -> Vec<u8> {
self.0
}
}
impl From<Vec<u8>> for Str {
fn from(v: Vec<u8>) -> Self {
Self(v)
}
}
impl From<&[u8]> for Str {
fn from(v: &[u8]) -> Self {
Self(v.to_vec())
}
}
impl<const N: usize> From<&[u8; N]> for Str {
fn from(v: &[u8; N]) -> Self {
Self(v.to_vec())
}
}
impl Readable for Str {
fn read(input: &mut Input) -> Self {
let mut res = Vec::new();
input.skip_whitespace();
while let Some(c) = input.get() {
if c.is_ascii_whitespace() {
break;
}
res.push(c);
}
Self(res)
}
}
impl Writable for Str {
fn write(&self, output: &mut Output) {
output.write_all(&self.0).unwrap()
}
}
impl Deref for Str {
type Target = Vec<u8>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Str {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl IntoIterator for Str {
type Item = u8;
type IntoIter = IntoIter<u8>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'a> IntoIterator for &'a Str {
type Item = &'a u8;
type IntoIter = std::slice::Iter<'a, u8>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a> IntoIterator for &'a mut Str {
type Item = &'a mut u8;
type IntoIter = std::slice::IterMut<'a, u8>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl FromIterator<u8> for Str {
fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
Self(iter.into_iter().collect())
}
}
impl AsRef<[u8]> for Str {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl AddAssign<&[u8]> for Str {
fn add_assign(&mut self, rhs: &[u8]) {
self.0.extend_from_slice(rhs)
}
}
impl Display for Str {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
unsafe { f.write_str(from_utf8_unchecked(&self.0)) }
}
}
pub trait StrReader {
fn read_str(&mut self) -> Str;
fn read_str_vec(&mut self, n: usize) -> Vec<Str>;
fn read_line(&mut self) -> Str;
fn read_line_vec(&mut self, n: usize) -> Vec<Str>;
fn read_lines(&mut self) -> Vec<Str>;
}
impl StrReader for Input<'_> {
fn read_str(&mut self) -> Str {
self.read()
}
fn read_str_vec(&mut self, n: usize) -> Vec<Str> {
self.read_vec(n)
}
fn read_line(&mut self) -> Str {
let mut res = Str::new();
while let Some(c) = self.get() {
if self.is_eol() {
break;
}
res.push(c);
}
res
}
fn read_line_vec(&mut self, n: usize) -> Vec<Str> {
let mut res = Vec::with_capacity(n);
for _ in 0..n {
res.push(self.read_line());
}
res
}
fn read_lines(&mut self) -> Vec<Str> {
let mut res = Vec::new();
while !self.is_exhausted() {
res.push(self.read_line());
}
if let Some(s) = res.last() {
if s.is_empty() {
res.pop();
}
}
res
}
}
}
}
}
詳細信息
Test #1:
score: 100
Accepted
time: 0ms
memory: 2148kb
input:
4 3 3 WBB BWB BBW 1 5 WWWWW 2 2 BB BB 4 1 W B B W
output:
YES 2 DDRR RRDD YES 0 YES 0 NO
result:
ok ok (4 test cases)
Test #2:
score: -100
Wrong Answer
time: 0ms
memory: 2140kb
input:
323 1 2 BB 1 2 BW 1 2 WB 1 2 WW 2 1 B B 2 1 B W 2 1 W B 2 1 W W 1 3 BBB 1 3 BBW 1 3 BWB 1 3 BWW 1 3 WBB 1 3 WBW 1 3 WWB 1 3 WWW 2 2 BB BB 2 2 BB BW 2 2 BB WB 2 2 BB WW 2 2 BW BB 2 2 BW BW 2 2 BW WB 2 2 BW WW 2 2 WB BB 2 2 WB BW 2 2 WB WB 2 2 WB WW 2 2 WW BB 2 2 WW BW 2 2 WW WB 2 2 WW WW 3 1 B B B 3 ...
output:
YES 1 R NO NO YES 0 YES 1 D NO NO YES 0 YES 1 RR NO NO NO NO NO NO YES 0 YES 0 NO YES 1 RD NO YES 1 DR NO YES 2 DR RD NO NO YES 2 DR RD NO YES 1 DR NO YES 1 RD NO YES 0 YES 1 DD NO NO NO NO NO NO YES 0 YES 1 RRR NO NO NO NO NO NO NO NO NO NO NO NO NO NO YES 0 YES 0 NO NO NO NO NO YES 1 RRD NO NO NO ...
result:
wrong answer Jury has answer but participant has not. (test case 75)