Rust Codeforces刷题模版
首先是最麻烦的输入输出模块,这里我封装了一个mod
,叫做IO
,使用这个模块就可以很方便地进行输入和输出了
mod io {
#[macro_export]
macro_rules! input {
() => {};
(mut $var:ident: $t:tt, $($rest:tt)*) => {
let mut $var = __input_inner!($t);
input!($($rest)*)
};
($var:ident: $t:tt, $($rest:tt)*) => {
let $var = __input_inner!($t);
input!($($rest)*)
};
(mut $var:ident: $t:tt) => {
let mut $var = __input_inner!($t);
};
($var:ident: $t:tt) => {
let $var = __input_inner!($t);
};
}
#[macro_export]
macro_rules! __input_inner {
(($($t:tt),*)) => {
($(__input_inner!($t)),*)
};
([$t:tt; $n:expr]) => {
(0..$n).map(|_| __input_inner!($t)).collect::<Vec<_>>()
};
([$t:tt]) => {{
let n = __input_inner!(usize);
(0..n).map(|_| __input_inner!($t)).collect::<Vec<_>>()
}};
(chars) => {
__input_inner!(String).chars().collect::<Vec<_>>()
};
(bytes) => {
__input_inner!(String).into_bytes()
};
(usize1) => {
__input_inner!(usize) - 1
};
($t:ty) => {
$crate::io::read::<$t>()
};
}
#[allow(unused)]
pub fn read<T>() -> T
where
T: std::str::FromStr,
T::Err: std::fmt::Debug,
{
use std::cell::RefCell;
use std::io::*;
thread_local! {
pub static STDIN: RefCell<StdinLock<'static>> = RefCell::new(stdin().lock());
}
STDIN.with(|r| {
let mut r = r.borrow_mut();
let mut s = vec![];
loop {
let buf = r.fill_buf().unwrap();
if buf.is_empty() {
break;
}
if let Some(i) = buf.iter().position(u8::is_ascii_whitespace) {
s.extend_from_slice(&buf[..i]);
r.consume(i + 1);
if !s.is_empty() {
break;
}
} else {
s.extend_from_slice(buf);
let n = buf.len();
r.consume(n);
}
}
std::str::from_utf8(&s).unwrap().parse().unwrap()
})
}
#[macro_export]
macro_rules! println {
($($arg:tt)*) => {
$crate::io::write(|w| {
use std::io::Write;
std::writeln!(w, $($arg)*).unwrap()
})
};
}
#[macro_export]
macro_rules! print {
($($arg:tt)*) => {
$crate::io::write(|w| {
use std::io::Write;
std::write!(w, $($arg)*).unwrap()
})
};
}
#[macro_export]
macro_rules! flush {
() => {
$crate::io::write(|w| {
use std::io::Write;
w.flush().unwrap()
})
};
}
#[allow(unused)]
pub fn write<F>(f: F)
where
F: FnOnce(&mut std::io::BufWriter<std::io::StdoutLock>),
{
use std::cell::RefCell;
use std::io::*;
thread_local! {
pub static STDOUT: RefCell<BufWriter<StdoutLock<'static>>> =
RefCell::new(BufWriter::new(stdout().lock()));
}
STDOUT.with(|w| f(&mut w.borrow_mut()))
}
}
这个模块的使用方式也很简单,如果在同一个文件内使用,不需要任何导入或者use
语句。
直接使用input macro
就可以很方便地输入输出
例子1,可以使用逗号隔开多个输入
input! { n: usize, m: usize }
例子2,可以使用嵌套的Vec
或者将变量当作Vec
长度
input! { n: usize, arr: [i32; n] }
可以使用基本上所有的内置类型和Vec
,当然也可以对Vec
进行嵌套,一个语句就可以输入多维数组
下面是一个适用于多组样例数据的main
函数和solve
函数模版,可以搭配上面的输入模块使用
fn main() {
input! { t :usize }
for _ in 0..t {
solve();
}
}
fn solve() {
}
为了方便大家导入VS Code
中,可以将以上两个模版写入VS Code
的用户代码片段中,具体的方式为Ctrl+Shift+P
打开命令面板,输入Configure User Snippets
,回车,再输入rust
,再回车,将如下内容粘贴到文件中即可
导入完成之后,就可以使用io
和sov
快捷键来快速键入这两个模块了
{
"Rust Solve Module": {
"prefix": "sov",
"body": [
"fn main() {",
" input!{ t: i32 }",
" for _ in 0..t {",
" solve();",
" }",
"}",
"",
"fn solve() {",
" $1",
"}"
]
},
"Rust IO Module": {
"prefix": "io",
"body": [
"mod io {",
" #[macro_export]",
" macro_rules! input {",
" () => {};",
" (mut \\$var:ident: \\$t:tt, \\$(\\$rest:tt)*) => {",
" let mut \\$var = __input_inner!(\\$t);",
" input!(\\$(\\$rest)*)",
" };",
" (\\$var:ident: \\$t:tt, \\$(\\$rest:tt)*) => {",
" let \\$var = __input_inner!(\\$t);",
" input!(\\$(\\$rest)*)",
" };",
" (mut \\$var:ident: \\$t:tt) => {",
" let mut \\$var = __input_inner!(\\$t);",
" };",
" (\\$var:ident: \\$t:tt) => {",
" let \\$var = __input_inner!(\\$t);",
" };",
" }",
"",
" #[macro_export]",
" macro_rules! __input_inner {",
" ((\\$(\\$t:tt),*)) => {",
" (\\$(__input_inner!(\\$t)),*)",
" };",
" ([\\$t:tt; \\$n:expr]) => {",
" (0..\\$n).map(|_| __input_inner!(\\$t)).collect::<Vec<_>>()",
" };",
" ([\\$t:tt]) => {{",
" let n = __input_inner!(usize);",
" (0..n).map(|_| __input_inner!(\\$t)).collect::<Vec<_>>()",
" }};",
" (chars) => {",
" __input_inner!(String).chars().collect::<Vec<_>>()",
" };",
" (bytes) => {",
" __input_inner!(String).into_bytes()",
" };",
" (usize1) => {",
" __input_inner!(usize) - 1",
" };",
" (\\$t:ty) => {",
" \\$crate::io::read::<\\$t>()",
" };",
" }",
" #[allow(unused)]",
" pub fn read<T>() -> T",
" where",
" T: std::str::FromStr,",
" T::Err: std::fmt::Debug,",
" {",
" use std::cell::RefCell;",
" use std::io::*;",
"",
" thread_local! {",
" pub static STDIN: RefCell<StdinLock<'static>> = RefCell::new(stdin().lock());",
" }",
"",
" STDIN.with(|r| {",
" let mut r = r.borrow_mut();",
" let mut s = vec![];",
" loop {",
" let buf = r.fill_buf().unwrap();",
" if buf.is_empty() {",
" break;",
" }",
" if let Some(i) = buf.iter().position(u8::is_ascii_whitespace) {",
" s.extend_from_slice(&buf[..i]);",
" r.consume(i + 1);",
" if !s.is_empty() {",
" break;",
" }",
" } else {",
" s.extend_from_slice(buf);",
" let n = buf.len();",
" r.consume(n);",
" }",
" }",
" std::str::from_utf8(&s).unwrap().parse().unwrap()",
" })",
" }",
"",
" #[macro_export]",
" macro_rules! println {",
" (\\$(\\$arg:tt)*) => {",
" \\$crate::io::write(|w| {",
" use std::io::Write;",
" std::writeln!(w, \\$(\\$arg)*).unwrap()",
" })",
" };",
" }",
"",
" #[macro_export]",
" macro_rules! print {",
" (\\$(\\$arg:tt)*) => {",
" \\$crate::io::write(|w| {",
" use std::io::Write;",
" std::write!(w, \\$(\\$arg)*).unwrap()",
" })",
" };",
" }",
"",
" #[macro_export]",
" macro_rules! flush {",
" () => {",
" \\$crate::io::write(|w| {",
" use std::io::Write;",
" w.flush().unwrap()",
" })",
" };",
" }",
" #[allow(unused)]",
" pub fn write<F>(f: F)",
" where",
" F: FnOnce(&mut std::io::BufWriter<std::io::StdoutLock>),",
" {",
" use std::cell::RefCell;",
" use std::io::*;",
"",
" thread_local! {",
" pub static STDOUT: RefCell<BufWriter<StdoutLock<'static>>> =",
" RefCell::new(BufWriter::new(stdout().lock()));",
" }",
"",
" STDOUT.with(|w| f(&mut w.borrow_mut()))",
" }",
"}"
]
}
}