Codeforces 1324B: Yet Another Palindrome Problem

Codeforces 1324B Rust 二解.

分析

这题本身是很水的. 所谓的存在回文子序列也就是存在两个相同的数字其中间还有其他数字. 这道题很好想到 $O(N^2)$ 的算法: 直接双重循环暴力搜索是否存在这两个数字就行了 (也就是改改循环上下限的问题); 另一个 $O(N)$ 或 $O(1)$ 的算法是使用哈希表维护每个数字在整个数组中最初和最末的位置.

代码

$O(N^2)$ 算法, 借鉴于 Codeforces 官方 Tutorial:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#[allow(unused_imports)]
use std::io::{BufWriter, stdin, stdout, Write};

#[derive(Default)]
struct Scanner {
buffer: Vec<String>
}
impl Scanner {
fn next<T: std::str::FromStr>(&mut self) -> T {
loop {
if let Some(token) = self.buffer.pop() {
return token.parse().ok().expect("Failed parse");
}
let mut input = String::new();
stdin().read_line(&mut input).expect("Failed read");
self.buffer = input.split_whitespace().rev().map(String::from).collect();
}
}
}

// codeforces' tutorial:
fn solve(v: &[u32]) -> bool {
let l = v.len();
for i in 0..l {
for j in (i + 2)..l {
if v[i] == v[j] {
return true;
}
}
}
false
}

fn main() {
let mut scan = Scanner::default();
let out = &mut BufWriter::new(stdout());

// Write code here
let t: usize = scan.next();
for _ in 0..t {
let n: usize = scan.next();
let v: Vec<u32> = (0..n).map(|_| scan.next()).collect();
if solve(&v) {
writeln!(out, "YES").ok();
} else {
writeln!(out, "NO").ok();
}
}
}

$O(N)$ 或 $O(1)$ 的算法是自己最先想到的. 以下仅提供 solve() 等关键部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#[derive(Debug)]
struct MN(usize, usize); // 分别存储最小最大索引位置

fn solve(v: &[u32]) -> bool {
let mut m: HashMap<u32, MN> = HashMap::new();
for (i, j) in v.iter().enumerate() {
if m.contains_key(j) { // can be simplified
let mn = m.get(j).unwrap();
m.insert(*j, MN(min(mn.0, i), max(mn.1, i)));
} else {
m.insert(*j, MN(i, i));
}
}
for (_, mn) in &m {
if mn.1 - mn.0 >= 2 {
return true;
}
}
false
}

Codeforces 1324B: Yet Another Palindrome Problem

https://blog.tamako.work/acmoi/codeforces/1324b/

Posted on

2024-04-01

Updated on

2024-04-01

Licensed under

Comments