67 lines
2.3 KiB
Rust
67 lines
2.3 KiB
Rust
use std::collections::HashMap;
|
|
|
|
fn solve_xor(image: &Vec<Vec<u8>>) {
|
|
let rows = image.len();
|
|
let cols = if rows > 0 { image[0].len() } else { 0 };
|
|
|
|
// 1. 차분 행렬 계산 (경계를 위해 크기를 +1)
|
|
// D[y][x] = P[y][x] ^ P[y-1][x] ^ P[y][x-1] ^ P[y-1][x-1]
|
|
let mut diff = vec![vec![0u8; cols + 2]; rows + 2];
|
|
for y in 1..=rows + 1 {
|
|
for x in 1..=cols + 1 {
|
|
let p = |r: usize, c: usize| if r <= rows && c <= cols { image[r-1][c-1] } else { 0 };
|
|
|
|
diff[y][x] = p(y, x) ^ p(y-1, x) ^ p(y, x-1) ^ p(y-1, x-1);
|
|
}
|
|
}
|
|
|
|
// 2. 스캔라인으로 짝 맞추기
|
|
let mut active_segments: HashMap<(usize, usize), usize> = HashMap::new();
|
|
let mut count = 0;
|
|
|
|
for y in 1..=rows + 1 {
|
|
let mut row_ones = Vec::new();
|
|
for x in 1..=cols + 1 {
|
|
if diff[y][x] == 1 {
|
|
row_ones.push(x);
|
|
}
|
|
}
|
|
|
|
// x좌표들을 두 개씩 짝지어 선분을 만듦
|
|
for chunk in row_ones.chunks_exact(2) {
|
|
let (x1, x2) = (chunk[0], chunk[1]);
|
|
let segment = (x1, x2);
|
|
|
|
if let Some(y_start) = active_segments.remove(&segment) {
|
|
// 이전에 시작된 같은 x범위의 선분이 있다면 사각형 완성!
|
|
count += 1;
|
|
println!("{}: XOR(L:{}, R:{}, T:{}, B:{})", count, x1, x2 - 1, y_start, y - 1);
|
|
} else {
|
|
// 새로운 선분 시작
|
|
active_segments.insert(segment, y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
// --- Figure-3 이미지 시뮬레이션 ---
|
|
// 문제의 예시대로 8x8 정도의 공간에 3개의 XOR을 수행해봅시다.
|
|
let mut img = vec![vec![0u8; 10]; 10];
|
|
|
|
fn apply_xor(img: &mut Vec<Vec<u8>>, l: usize, r: usize, t: usize, b: usize) {
|
|
for y in t..=b {
|
|
for x in l..=r {
|
|
img[y-1][x-1] ^= 1; // 1-based to 0-based
|
|
}
|
|
}
|
|
}
|
|
|
|
println!("--- Figure-3 시뮬레이션 시작 ---");
|
|
apply_xor(&mut img, 2, 4, 2, 6); // Fig-1 생성
|
|
apply_xor(&mut img, 3, 6, 4, 7); // Fig-2 생성
|
|
apply_xor(&mut img, 1, 3, 3, 5); // Fig-3 완성
|
|
|
|
// 이제 이 '이미지 결과물'만 보고 원래의 XOR 호출을 찾아내는지 확인
|
|
solve_xor(&img);
|
|
} |