https://www.acmicpc.net/problem/9663

 

9663번: N-Queen

N-Queen 문제는 크기가 N × N인 체스판 위에 퀸 N개를 서로 공격할 수 없게 놓는 문제이다. N이 주어졌을 때, 퀸을 놓는 방법의 수를 구하는 프로그램을 작성하시오.

www.acmicpc.net

 

문제분석

백준 9663번 N-Queen 문제입니다. 굉장히 유명한 문제 중 하나입니다.

 

완전탐색으로 풀 수 있는것으로 알려져있습니다.

 

N이 15인데, 그러면 체스 말 판이 15x15=225칸이 있고, 이 중 15칸을 고른다고 하면

 

경우의 수가 //(\scriptstyle 225\textstyle C\scriptstyle 15//) 가 되는데, 뭐, 대충 계산해봐도

 

1억이라는 수를 훌쩍 넘는 것을 알 수 있습니다. //(100^{10}//)라고만 봐도 //(10^{20}//)이 되니깐, 1억이 //(10^8//)인 것을 감안하면 안되는 경우의 수가 되지요.

 

여기서 무조건 아닌 수를 조금 줄여보도록 하면,

 

퀸이 같은 행이나 열에 있으면 공격할 수 있으므로 각자 다른 열이나 행에 두어야 합니다.

 

그러면 NxN의 체스판에 퀸을 N개를 두려면 1행에 있는 퀸, 2행에 있는 퀸... N행에 있는 퀸이 최대 1개씩 밖에 있을 수 없습니다.

 

그리고 열에도 퀸은 최대 1마리만 둘 수 있기 때문에 이 조건을 맞추어 퀸을 배열하는 경우의 수는

 

1부터 N까지의 수를 한 줄로 나열하는 경우의 수와 같다고 볼 수 있습니다.

 

즉 //(N!//)이 되지요.

 

예를들어 //(N=4//)이고 //(1,3,2,4//)와 같이 배열한다는 것은 퀸을 (1,1), (2,3), (3,2), (4,4)에 배열한다는 뜻으로 볼 수 있습니다.

 

 

 

여기서 //(N=15//)일 때 //(15!=1307674368000//)인데 이 수도 여전히 큽니다.

 

하지만 퀸을 배치하다가 대각선으로 서로 공격할 수 있는 경우, 더이상 탐색하지 않는 가지치기(pruning)을 적용을 하면 저 수 보다는 적은 수의 탐색으로 경우의 수를 모두 찾아 볼 수가 있습니다.

 

구현전략

일단 완전탐색 문제이므로 제귀를 활용한 dfs로 탐색을 하면 쉽게 구현을 할 수 있습니다.

 

N개의 수를 나열하는 문제에 + 퀸이 대각선으로 공격할 수 있다는 점을 체크를 해야 합니다.

 

같은 대각선에 있는 좌표는 x좌표+y좌표의 값이 같거나, x좌표-y좌표의 값이 같습니다. 

 

이게 왜 그런가 하는지는 엑셀 등에 직접 좌표마다 값을 구해서 눈으로 보면 간단하며,

 

1차함수의 그래프를 그려봐도 마찬가지로 쉽게 알 수 있습니다.

 

x+y=k의 그래프를 그리면 2차원 좌표계에서 좌측상단에서 우측하단으로 뻗는 직선의 그래프를 확인할 수 있습니다.

x-y=k의 그래프 역시 2차원 좌표계에서 우측상단에서 좌측하단으로 뻗는 직선의 그래프를 확인할 수 있습니다.

 

이러한 점을 고려해서 제귀로 구현하면 생각보다 간단하게 구현할 수 있습니다.

 

코드

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
/*
N=15일때
좌표계가 (0,0) ~ (14,14)라고 볼때,
*/
int pl[35]; // 0 ~ 28
int mi[35]; // 14 ~ -14
bool num[15];
int val[15];
int ans;
int n;
void dfs(int x) {
	if (x == n) {
		ans++;
		return;
	}
	for (int y = 0; y < n; y++) {
		if (num[y] == false && pl[x+y] == false && mi[x-y+14] == false) {
			val[x] = y;
			num[y] = pl[x + y] = mi[x - y + 14] = true;
			dfs(x + 1);
			num[y] = pl[x + y] = mi[x - y + 14] = false;
		}
	}
}
int main() {
	cin >> n;
	dfs(0);
	cout << ans << endl;
}

코드포스 컨테스트를 치르고 나면 항상 결과가 궁금해지죠. 특히나 레이팅의 변화가 어떻게 될 것인지가 초유의 관심사 중 하나 일 것입니다.

 

Contest가 끝나고 System Test이 끝날 때 까지 기다린 뒤, 수 시간 정도 지나야지 레이팅 변화가 적용이 됩니다.

 

이를 미리 알아볼 수 있는, 즉 레이팅 변화를 예측하게 해주는 웹 사이트가 있는데요.

 

https://cf-predictor-frontend.herokuapp.com/

 

CF-Predictor

 

cf-predictor-frontend.herokuapp.com

 

위 링크로 들어간 뒤 본인이 참여한, 혹은 레이팅 변화를 예측해보고 싶은 대회를 선택한 뒤 기다리시면 됩니다.

 

참여한 모든 인원에 대한 데이터를 표로 한번에 보여주므로, 모바일에서 보는 경우 데이터 폭탄을 맞을 수도 있으니 주의 해주시면 되겠습니다.

 

 

https://codeforces.com/blog/entry/50411

 

CF-Predictor — Know your rating changes! - Codeforces

 

codeforces.com

 

해당 CF-Predictor를 만든 사람이 홍보하는 코드포스 블로그도 있습니다.

 

크롬 익스텐션으로도 있다고 하니, 관심있으면 설치해보시는 것도 좋을 것 같습니다.

 

https://chrome.google.com/webstore/detail/cf-predictor/ocfloejijfhhkkdmheodbaanephbnfhn

 

CF-Predictor

This extension predicts rating changes for Codeforces. It shows approximate deltas during and after the contest.

chrome.google.com

 

덧붙여서 코드포스 레이팅 시스템은 ELO 라는 많이 쓰이는 방식을 쓴다고 하니, 관심있으시면 아래 링크에서 좀 더 읽어보셔도 좋을 것 같습니다.

https://codeforces.com/blog/entry/20762

 

Open Codeforces Rating System [updated on October 2015] - Codeforces

 

codeforces.com

 

 

(레이팅이 떨어져서 심란한 차에 쓴 글입니다 ㅜㅜ)

알고리즘 문제를 풀다 보면 그래프를 그려봐야 하는 경우 

 

손으로 직접 그리면 번거롭고 노드 갯수가 많은 경우 그리기가 힘들 수 있는데, 이를 간단하게 해결해주는 사이트가 있다.

 

 

 

https://csacademy.com/app/graph_editor/

 

CS Academy

 

csacademy.com

 

csacademy라는 사이트는 코드포스와 탑코더처럼 온라인 알고리즘 콘테스트를 열어주는 그런 사이트인데, 거기 툴중에 그래프 에디터가 있습니다.

 

사용방법도 직관적이고, 유용합니다.

 

왼쪽에 있는 창에 Graph Data를 쓰면 됩니다. Node Count이런것들은 자동으로 생성되므로, 크게 신경쓰지 않아도 되고

 

한 줄에 하나의 숫자만 쓰면, Node가 있음을 선언하는 것이고, 한 줄에 두개의 숫자를 쓰면 왼쪽 노드 번호에서 오른쪽 번호 노드로 가는 Edge가 있는 것을 알려주는 것입니다.

 

무향/방향 그래프임을 위에 Undirected / Directed 버튼으로 결정할 수 있습니다.

 

 

오른쪽 트레이에 보면 상단에 5개 정도 패널이 있는데 각각 모드를 설정할 수 있습니다.

 

Force모드면 노드를 드래그 앤 드롭하면 탄력적으로 움직이고, Draw모드를 하면 이동하고 위치가 고정됩니다.

 

Edit모드는 이미지 상에서 노드 이름을 변경하거나 Edge의 Weight값을 결정하는 등 여러가지가 가능합니다.

 

특히나 Config 패널로 가서 Run Command -> Arrange as Tree로 하면 트리모양으로 그래프를 배열해줍니다.

 

싸이클이 있는 그래프이므로 완전한 Tree모양으로 배열해주진 않지만, 얼추 트리에 가까운 모양으로 배열해줍니다.

 

백문이 불여일견인 툴이므로, 접속해서 애용해봅시다.

+ Recent posts