Editorial for Đặc vụ bí mật
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
Cách làm tối ưu là thực hiện thao tác ~\texttt{ap} \to \texttt{ptp}~ theo thứ tự từ phải qua trái. Sau đó thực hiện thao tác ~\texttt{ptp} \to \texttt{ap}~ theo thứ tự từ trái sang phải.
Dưới đây là một số quan sát để nhận thấy tại sao cách làm trên đúng. Phần chứng minh xin nhường lại cho độc giả:
- Tổng số kí tự
avàttrong cả xâu là hằng số. - Có thể nhận thấy lúc nào cũng có thể biến đổi ~\texttt{ap} \to \texttt{ptp}~. Ta lúc nào cũng có thể biến đổi ~\texttt{ptp}~ này ngược lại về ~\texttt{ap}~ do nhóm 3 kí tự này không thể bị thay đổi tiếp bởi thao tác ~\texttt{ap} \to \texttt{ptp}~~\texttt{ap} \to \texttt{ptp}~ khác.
- Khi thực hiện ~\texttt{ap} \to \texttt{ptp}~ từ trái qua, ta có thể biến đổi nhóm kí tự
ptaaaa...aaapthànhptptptpt...ptp. Khi áp dụng ~\texttt{ptp} \to \texttt{ap}~ theo thứ tự từ trái sang phải, ta có thể khử kí tựtđầu tiên, biến nó thànhaaaaaaa...aaap. Chỉ có nhóm kí tự loại này bị thay đổi như vậy, đó cách làm sẽ cho ra xâu kí tự nhỏ nhất.
use std::io::*; // Note: // - This function consume s // - The returned value is **reversed**. fn do_replace(mut s: Vec<u8>, from: &[u8], to: &[u8]) -> Vec<u8> { let mut t = vec![]; while s.len() > 0 { if s.ends_with(from) { s.truncate(s.len() - from.len()); s.extend_from_slice(&to); } else { t.push(s.pop().unwrap()); } } t } fn main() { let mut writer = std::io::BufWriter::new(stdout().lock()); let stdin = stdin(); let read_line = || { let mut input = String::new(); stdin.read_line(&mut input).unwrap(); input.trim().to_string() }; let t = read_line().parse::<usize>().unwrap(); for _ in 0..t { let s = read_line(); let s = s.trim().as_bytes().to_vec(); let s = do_replace(s, b"ap", b"ptp"); let s = do_replace(s, b"ptp", b"pa"); // because we reversed the string writeln!(writer, "{}", s.len()).unwrap(); } }
Comments