https://www.acmicpc.net/problem/3344
백트래킹에서 유명한 문제 중 하나인 N-Queen이다.
N값을 입력받고 N * N 크기의 체스판에 N개의 서로 공격하지 못하는 위치에 퀸을 놓는 것.
그런데... 문제가 좀 다르다.
N의 값은 8, 26, 213, 2012, 99991, 99999 중 하나로 정해주었다.
그리고 만족하는 퀸들의 위치를 아무거나 한 개씩만 출력하면 되는 문제이다.
N값 중 99991, 99999이 존재하는 것으로 보아 시간복잡도가 O(n2) 이상이면 시간 초과가 날 것이다.
백트래킹 관련 문제를 별로 풀어본 적도 없어서 공부도 할 겸 백트래킹으로 짜보았으나 역시 시간초과로 실패했다.
번뜩 생각이 난게 같은 x, y축, 대각선의 조건을 거스는 것이 하나 있었다.
나이트는 한 칸 전진 후 대각 방향으로 또 한번을 전진하는데, 각 퀸들이 서로 나이트가 갈 수 있는 경로 상에 있으면 된다.
그렇다면 무언가 규칙이 있다는 셈인데 위키백과가 그 답을 가지고 있었다.
https://en.wikipedia.org/wiki/Eight_queens_puzzle#Explicit_solutions
Explicit_solutions 탭에 조건과 규칙이 명시되어 있다.
이대로 소스코드를 짜면 끝이다.
#include <cstdio> int main() { int n; bool isOdd = false; scanf("%d", &n); if (n % 2) isOdd = true; if ((!isOdd && n % 6 != 2) || (isOdd && (n - 1) % 6 != 2)) { if (isOdd) n--; for (int i = 1; i <= n / 2; i++) printf("%d\n", 2 * i); for (int i = 1; i <= n / 2; i++) printf("%d\n", 2 * i - 1); if (isOdd) printf("%d\n", n + 1); } else if ((!isOdd && n / 6 != 0) || (isOdd && (n - 1) / 6 != 2)) { if (isOdd) n--; for (int i = 1; i <= n / 2; i++) printf("%d\n", 1 + (2 * i + n / 2 - 3) % n); for (int i = n / 2; i > 0; i--) printf("%d\n", n - (2 * i + n / 2 - 3) % n); if (isOdd) printf("%d\n", n + 1); } return 0; }
'알고리즘' 카테고리의 다른 글
BOJ [1676] 팩토리얼 0의 갯수 (0) | 2017.08.10 |
---|---|
BOJ [1874] 스택 수열 (0) | 2017.08.10 |
BOJ [1011] Fly me to the Alpha Centauri (0) | 2017.08.10 |
BOJ [1463] 1로 만들기 (0) | 2017.08.10 |
BOJ [6588, 9020] 골드바흐의 추측 (0) | 2017.08.10 |