Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

8 Queens Problem

The goal of 8 Queens Problem is to put eight queens on a chess-board such that none of them threatens any of others. A queen threatens the squares in the same row, in the same column, or on the same diagonals as shown in the following figure.

For a given chess board where $k$ queens are already placed, find the solution of the 8 queens problem.

Input

In the first line, an integer $k$ is given. In the following $k$ lines, each square where a queen is already placed is given by two integers $r$ and $c$. $r$ and $c$ respectively denotes the row number and the column number. The row/column numbers start with 0.

Output

Print a $8 \times 8$ chess board by strings where a square with a queen is represented by 'Q' and an empty square is represented by '.'.

Constraints

There is exactly one solution

Sample Input 1

2
2 2
5 3

Sample Output 1

......Q.
Q.......
..Q.....
.......Q
.....Q..
...Q....
.Q......
....Q...

Solution in Rust (judge verdict: Accepted)

use std::collections::HashSet;


fn main() {
    let n: usize = read();
    let mut queen_pos: Vec<Option<usize>> = vec![None; 8];
    for _ in 0..n {
        let (r, c) = read_tuple::<usize>();
        queen_pos[r] = Some(c);
    }

    let permutation = dfs(&mut vec![], &mut vec![false; 8]);

    for posc in permutation.iter() {
        let mut table = vec![vec!['.'; 8]; 8];
        let mut not_access: HashSet<(usize, usize)> = HashSet::new();
        let mut check = true;
        for (r, c) in posc.iter().enumerate() {
            if let Some(v) = queen_pos[r] {
                if *c != v {
                    check = false;
                    break;
                } 
            }

            if not_access.contains(&(r, *c)) {
                check = false;
                break;
            }

            table[r][*c] = 'Q';

            for i in 1..8 {
                let cond = (r >= i, *c >= i, r + i < 8, c + i < 8);
                if cond.0 && cond.1 {
                    not_access.insert((r - i, c - i));
                }
                if cond.0 && cond.3 {
                    not_access.insert((r - i, c + i));
                }
                if cond.1 && cond.2 {
                    not_access.insert((r + i, c - i));
                }
                if cond.2 && cond.3 {
                    not_access.insert((r + i, c + i));
                }
            }
        }

        if check {
            for line in table.iter() {
                println!("{}", line.iter().collect::<String>());
            }
            break;
        }
    }
}


fn dfs(cur: &mut Vec<usize>, flag: &mut Vec<bool>) -> Vec<Vec<usize>> {
    if flag.iter().all(|x| *x) {
        return vec![cur.clone()]
    }

    let mut res = Vec::new();
    for i in 0..flag.len() {
        if !flag[i] {
            flag[i] = true;

            cur.push(i);
            res.append(&mut dfs(cur, flag));
            cur.pop();

            flag[i] = false;
        }
    }

    res
}

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().split_whitespace()
        .map(|e| e.parse().ok().unwrap()).collect()
}

fn read_tuple<T: std::str::FromStr + Copy>() -> (T, T) {
    let temp = read_vec();
    (temp[0], temp[1])
}