题目

思路来源
heltion代码、International_River代码
题解
找到一条1到1的最短路,记录前驱,标记成不可达,然后再找2到2的最短路
对称的,先找1再找2,和先找2再找1都跑一遍,有一个找到就是有解,否则就是无解
这个是常规做法
比较惊艳的是这个分类讨论,
只要出现以下三种情况就无解,否则就有解
-
交叉
-
卡角(两个数字把一个数字堵在一个角落)
-
四个数字均位于四条边上,且顺时针考虑它们的时候,第一个数字和第三个数字是同一个数字
代码1(最短路)
cpp
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define all(x) (x).begin(),(x).end()
typedef long long i64;
typedef pair<int, int> pii;
const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, 1, -1};
bool solve(vector<string> mp, char a, char b) {
// cerr << a << b << endl << endl;
int n = mp.size(), m = mp[0].length();
vector f(n, vector<pii>(m, pii(-1, -1)));
queue<pii> q; pii p;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(mp[i][j] == a) {
if(q.empty()) {
q.push(pii(i, j));
mp[i][j] = '4';
} else {
p = {i, j};
}
}
}
}
while(!q.empty()) {
auto [u, v] = q.front();
q.pop();
for(int i = 0; i < 4; i++) {
int nu = u + dx[i];
int nv = v + dy[i];
if(nu < 0 || nv < 0 || nu >= n || nv >= m) continue;
if(mp[nu][nv] != '0' && mp[nu][nv] != a) continue;
f[nu][nv] = {u, v};
mp[nu][nv] = '3';
q.push({nu, nv});
}
}
if(f[p.first][p.second].first == -1) return false;
while(p.first != -1) {
mp[p.first][p.second] = a;
p = f[p.first][p.second];
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(mp[i][j] == '3') {
mp[i][j] = '0';
}
}
}
// for(auto s : mp) cerr << s << endl; cerr << endl;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(mp[i][j] == b) {
if(q.empty()) {
q.push(pii(i, j));
mp[i][j] = '4';
} else {
p = {i, j};
}
}
}
}
while(!q.empty()) {
auto [u, v] = q.front();
q.pop();
for(int i = 0; i < 4; i++) {
int nu = u + dx[i];
int nv = v + dy[i];
if(nu < 0 || nv < 0 || nu >= n || nv >= m) continue;
if(mp[nu][nv] != '0' && mp[nu][nv] != b) continue;
f[nu][nv] = {u, v};
mp[nu][nv] = '3';
q.push({nu, nv});
}
}
if(f[p.first][p.second].first == -1) return false;
return true;
}
void solve() {
int n, m; cin >> n >> m;
vector<string> mp(n);
for(auto &s : mp) cin >> s;
bool yes = solve(mp, '1', '2') || solve(mp, '2', '1');
cout << (yes ? "YES" : "NO") << endl;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T; cin >> T;
while(T--) solve();
return 0;
}
代码2(分类讨论)
rust
use std::{
cell::RefCell,
fmt::Debug,
io::{BufWriter, Read, Stdout},
str::{FromStr, SplitAsciiWhitespace},
};
thread_local! {
static INPUT: RefCell<SplitAsciiWhitespace<'static>> = RefCell::<SplitAsciiWhitespace<'static>>::new({
let mut input = String::new();
std::io::stdin().read_to_string(&mut input).unwrap();
Box::leak(input.into_boxed_str()).split_ascii_whitespace()
});
pub static OUTPUT: RefCell<BufWriter<Stdout>> = RefCell::new(BufWriter::new(std::io::stdout()));
}
pub fn read<T: FromStr>() -> T
where
T::Err: Debug,
{
INPUT.with(|input| input.borrow_mut().next().unwrap().parse().unwrap())
}
pub fn read_string() -> Vec<u8> {
INPUT.with(|input| input.borrow_mut().next().unwrap().as_bytes().to_vec())
}
#[macro_export]
macro_rules! expand {
($arg:expr) => {
$arg.into_iter()
.map(|x| x.to_string())
.collect::<Vec<_>>()
.join(" ")
};
}
#[macro_export]
macro_rules! output {
($($arg:expr),*) => {
OUTPUT.with(|output| {
use std::io::Write;
writeln!(output.borrow_mut(), "{}", [$($arg.to_string()),*].join(" ")).unwrap();
});
};
}
#[macro_export]
macro_rules! debug {
($($arg:expr),*) => {
#[cfg(debug_assertions)]
eprintln!("[{}:{}] {}", file!(), line!(), [$(format!("{} = {:?}", stringify!($arg), $arg)),*].join(", "));
};
}
fn main() {
fn solve() -> &'static str {
let n: usize = read();
let m: usize = read();
let s: Vec<_> = (0..n).map(|_| read_string()).collect();
for i in 0..n - 1 {
for j in 0..m - 1 {
if s[i][j] != b'0'
&& s[i + 1][j] != b'0'
&& s[i][j + 1] != b'0'
&& s[i + 1][j + 1] != b'0'
{
if s[i][j] == s[i + 1][j + 1] {
return "NO";
}
}
}
}
let corner = [
((0, 0), (0, 1), (1, 0)),
((0, m - 1), (0, m - 2), (1, m - 1)),
((n - 1, 0), (n - 2, 0), (n - 1, 1)),
((n - 1, m - 1), (n - 2, m - 1), (n - 1, m - 2)),
];
for &((x, y), (a, b), (c, d)) in &corner {
if s[x][y] != b'0' && s[a][b] != b'0' && s[c][d] != b'0' {
if s[a][b] == s[c][d] {
return "NO";
}
}
}
let mut answer = vec![];
for i in 0..m - 1 {
if s[0][i] != b'0' {
answer.push(s[0][i]);
}
}
for i in 0..n - 1 {
if s[i][m - 1] != b'0' {
answer.push(s[i][m - 1]);
}
}
for i in (1..m).rev() {
if s[n - 1][i] != b'0' {
answer.push(s[n - 1][i]);
}
}
for i in (1..n).rev() {
if s[i][0] != b'0' {
answer.push(s[i][0]);
}
}
if answer.len() == 4 && answer[0] == answer[2] {
return "NO";
}
"YES"
}
for _ in 0..read() {
output!(solve());
}
}