こんにちは!グンです。
今回は有名なアルゴリズム問題である
N-Queenです。
안녕하세요! 근입니다.
이번에는 유명한 알고리즘 문제인
N-Queen입니다.
ソース(출처):https://www.acmicpc.net/problem/9663
問題 / 문제
N x Nのチェス盤の上にクイーンN個をお互い攻撃出来ないようにおく問題です。
Nが与えられた場合、クイーンを置く方法の数を出すプログラムを作成して下さい。
N-Queen 문제는 크기가 N × N인 체스판 위에 퀸 N개를 서로 공격할 수 없게 놓는 문제이다.
N이 주어졌을 때, 퀸을 놓는 방법의 수를 구하는 프로그램을 작성하시오.
入力 / 입력
最初のラインにNが与えられる。(1 ≤ N < 15)
첫째 줄에 N이 주어진다. (1 ≤ N < 15)
出力 / 출력
最初のラインにお互い攻撃出来ない場合の数を出力する。
첫째 줄에 서로 공격할 수 없는 경우의 수를 출력한다.
例 / 예시
番号 / 번호 | 入力 / 입력 | 出力 / 출력 |
---|---|---|
1 | 8 | 92 |
私の考え / 나의 생각
N x Nのチェス盤の最初の行から最後の行までクイーンを置いてみる。
置けない場合は以前のクイーンの位置を変える。
最後の行まで辿り着いたならカウントを増加させる。
最初の行の検査がNに行くまで繰り返す。
N x N의 체스판의 처음 행에서 마지막 행까지 퀸을 놓아본다.
놓을 수 없는 경우는 이전의 퀸 위치를 바꾼다.
마지막 행까지 도닥하면 카운드를 증가시킨다.
마지막 행의 검사가 N까지 갈 때까지 반복한다.
コード
import java.util.Scanner;
class Main {
static int count = 0;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt(); // 1)
int[] col = new int[n];
for(int i=0;i<n;i++) { // 2)
col[0] = i;
nqueen(0,col);
}
System.out.println(count); // 5)
input.close();
}
public static boolean rule(int index, int col[]) { // 4)
int k = 0;
boolean swit = true;
while(k < index && swit) {
if(col[k] == col[index] || Math.abs(col[k] - col[index]) == index - k) {
swit = false;
}
k++;
}
return swit;
}
public static void nqueen(int index, int[] col) { // 3)
if(rule(index,col)) {
if(index == col.length-1) {
count++;
}
else {
for(int i=0;i<col.length;i++) {
col[index + 1] = i;
nqueen(index+1,col);
}
}
}
}
}
1)
Nの入力を貰って、Nの大きさの配列を宣言する。各配列の値は、対応する行内の列の位置を意味します。
N의 입력을 받고, N 크기의 배열을 선언한다. 각 배열의 값은 해당하는 행의 열의 위치를 의미한다.
2)
最初の行に対応する配列のIndexに位置の情報をNまで更新しながらnqueen関数をよぶ。
첫째 열에 해당하는 배열의 인덱스에 위치 정보를 N까지 갱신하면서 nqueen함수를 부른다.
3)
クイーンを置けるルールを検査する。
置ける位置の場合、現在の行がNの場合カウントを増加するし、Nじゃなかったら次の行に位置を書いて同じことを繰り返す。
퀸을 놓을 수 있는 규칙을 검사한다.
놓을 수 있는 위치일 경우, 현재 행이 N일 경우 카운트를 증가시키고, N이 아닐 경우 다음 행에 위치를 적고 같은 것을 반복한다.
4)
検査しようとしている行の以前の行を全部検査する。
直線上の位置と対角線上の位置に配置できないため、その線の上に置こうとしている場合はfalseをreturnする。
검사하려고 하는 행의 이전의 행을 전부 검사한다.
직선 위의 위치와 대각선 위의 위치에 배치할 수 없기 때문에, 그 선 위에 놓으려고 하는 경우는 false를 리턴한다.