기금넷 공식사이트 - 복권 조회 - 8 황후 c++ 소스 코드 해석

8 황후 c++ 소스 코드 해석

회고: 8 황후 문제, 고전적인 문제

프로그래밍에는' 역추적 방법' 이라는 방법도 있습니다. 그것은 일정한 공식이나 일정한 법칙에 따라 문제의 해법을 찾는 것이 아니라, 잘못된 전략을 시험해 문제의 거리를 찾는 것이다. 이 방법은 일반적으로 원래 상태에서 시작하여 여러 단계의 시험 오류로 끝납니다.

이론적으로 역추적 방법은 검색 트리의 루트 노드에서 시작하여 특정 조건을 충족하는 하위 노드에 대한 경로를 찾는 것입니다. 검색 중 각 중간 노드에 대한 위치 및 하향 검색 프로세스는 유사하므로 재귀적으로 처리할 수 있습니다. 전형적인 예는 유명한' 팔황후 문제' 이다.

팔황후' 의 문제는 여덟 명의 황후를 바둑판 위에 놓아서 서로 먹을 수 없게 하는 것이다. 체스의 황후는 그녀와 같은 줄에 대각선을 이루는 바둑을 먹을 수 있기 때문에 행당 황후 한 명만 놓을 수 있다. 8 행이 있기 때문에 행당 황후가 한 명밖에 없다.

이 예에서 황후의 위치에는 A(I)=J 를 저장할 1 차원 배열이 있습니다. 즉, I 행의 황후는 J 열에 배치됩니다. 여왕이 안전한지 아닌지를 판단하는 방법에 주로 달려 있다. (1) 먼저 1 차원 배열로 같은 줄에 있지 않은 문제를 해결했습니다. (2) 이 열에 플래그 배열 C[J] 를 도입할 수 있습니다. 만약 황후가 J 기둥에 놓인다면. 왼쪽 아래 구석과 오른쪽 위 구석의 대각선의 경우 I+J 는 상수와 같습니다. 배열 R [2 로 표시 .. 16]. 여왕이 I 행 j 열에 배치되면 c [j]: = false; L [I-j]: = flase; R[I+J]:=FALSE 는 여왕의 안전 문제를 해결할 수 있습니다.

문제 설명: 8 명의 황후를 표준 바둑판 (8*8 격) 에 올려놓을 예정이다. 우리는 황후가 체스 중에서 가장 강하다는 것을 안다. 그녀는 가로로 걸을 수도 있고, 세로로 갈 수도 있고, 비스듬히 걸을 수도 있다. 그녀가 길을 막는 적을 만났을 때, 그녀는 상대를 잡아먹을 수 있었다. 여덟 명의 황후를 바둑판 위에 놓아서 서로 먹을 수 없도록 하고 황후 석방을 요구하다.

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

/* */

/* 질문: 8×8 의 바둑판에 8 명의 황후를 놓고 두 명의 황후를 요구하다 */

/* 같은 행, 열 또는 대각선에 있을 수 없습니다. */

/* */

/* 이 프로그램은 재귀-역추적 방법을 사용하여 8 황후 문제를 해결합니다. Visual C++ 6.0 디버깅을 통과했습니다. */

/* 저자 모닝스타사 2002 년 5 월 9 일 */

/* */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

# include & ltstdio.h & gt

# include & ltconio.h & gt

# include & ltmath.h & gt

# 여왕 정의 8

//! 솔루션 일련 번호를 기록하는 글로벌 변수.

Inticount = 0;

//! 여왕이 각 열에 배치되는 위치를 기록하는 전역 배열입니다.

Intsite [queens];

//! 재귀적으로 해결하는 함수.

허공 여왕 (int n);

//! 하나의 해결책을 출력하다.

Void 출력 ();

//! N 번째 여왕이 올라간 후 충돌이 있는지 판단하다.

Int is valid (int n);

/*-main: 주 함수. -*/

Void main ()

{

//! 재귀적 탐구법은 0 열부터 시작한다.

여왕 (0);

//! 아무 키나 눌러 돌아옵니다.

Getch ();

}

/*-Queen: n 번째 황후 재귀적으로 배치, 프로그램의 핵심! -*/

허공 여왕 (정수)

{

Int I;;

//! 매개 변수 N 은 0 부터 시작하여 8 일 때 솔루션을 시도하고 출력하고 백트래킹합니다.

If(n == 여왕)

{

Output ();

반환;

}

//! N 은 아직 8 이 되지 않았습니다. N 번째 열의 각 행에서 순서대로 시도합니다.

For (I =1; 나<= 퀸즈; I++)

{

//! 황후를 기둥의 I 선에 올려놓다.

사이트 [n] = I;

//! 배치에 충돌이 없는 경우 다음 열이 테스트됩니다.

If(IsValid(n))

황후 (n+1);

}

}

/*-IsValid: N 번째 여왕이 입고 나서 합법적인지, 즉 충돌하지 않는지 판단합니다. -*/

Int IsValid(int n)

{

Int I;;

//! N 번째 황후와 이전 n- 1 개 황후의 위치를 비교하다.

For(I = 0;; 나 & ltn;; I++)

{

//! 두 황후가 같은 선에 있어서 0 을 반환합니다.

If (사이트 [i] == 사이트 [n])

0 을 반환합니다

//! 두 황후는 같은 대각선에 0 을 반환합니다.

If (ABS (사이트 [I]-사이트 [n]) = = (n-I))

0 을 반환합니다

}

//! 충돌하지 않고 1 을 반환합니다.

1;

}

/*-output: 솔루션, 즉 충돌 없는 레이아웃 시나리오를 출력합니다. -*/

잘못된 출력 ()

{

Int I;;

//! 출력 일련 번호.

Printf ("번호 %-5d",++icount);

//! 각 열에서 여왕의 위치, 즉 행 수를 차례로 출력합니다.

For(I = 0;; 나< 퀸즈; I++)

Printf("%d ",사이트 [I]);

Printf ("n");

}

STL 소스 코드

STL 의 경우 방법은 동일합니다.

# include & ltiostream & gt

# include & lt 문자열>

네임스페이스 STD 사용

Void queen (상수 문자열 t, 상수 문자열 s)

{

If (s = = "") cout < & ltt<& ltendl

기타

For(int I = 0;; 나 & lts.length () 입니다. I++) {

Bool safe = true

For(int j = 0;; J & ltt.length (); J++) {

If (t.length ()-j = = ABS (s [I]-t [j]) safe = false;

}

If (safe) queen(t+s[i], s.substr(0, I)+s.substr (I+1)))

}

}

Int main ()

{

Strings = "01234567";

황후 (",S);

시스템 ("일시 중지");

종료 (exit _ success);

}

팔황후 문제를 재귀적으로 해결하다

/* 재귀적인 방법으로 팔황후 문제 해결 */

/* 저자 황국우, 데이터 구조 (C 어판) 칭화대 출판사 */

충전 보드 [8] [8]; /* 문 8 * 8 의 빈 바둑판 */

Int n _ queens (int locx, int locy, int queens)/* recursion */

{

Int I, j;

Intresult = 0;

If(Queens == 8)/* 반복 종료 조건 */

1;

Else if (queen place (locx, locy))/* 반복 실행 부분 */

{

바둑판 [locx] [locy] =' q';

For(I = 0;; 나<8; I++)

For(j = 0;; J<8; J++)

{

Result += N_Queens(i, j, queens+1);

If (결과>0)

깨뜨리다

}

If (결과>0)

1;

기타

{

바둑판 [locx] [locy] =' x';

}

}

기타

0 을 반환합니다

}

Int queen place (int locx, int locy)/* 단어 좌표 자체와 8 개의 대화 방향에 여왕이 있는지 판단한다 */

{

Int I, j;

If (바둑판 [LocX][LocY]! = 'X')

0 을 반환합니다

For (j = locy-1; J & gt=0; J-)

If (바둑판 [LocX][j]! = 'X')

0 을 반환합니다

For (j = locy+1; J<8; J++)

If (바둑판 [LocX][j]! = 'X')

0 을 반환합니다

For (I = locx-1; 나 & gt=0; 나-)

If (바둑판 [i][LocY]! = 'X')

0 을 반환합니다

For (I = locx+1; 나<8; I++)

If (바둑판 [i][LocY]! = 'X')

0 을 반환합니다

I = locx-1;

J = locy-1;

While(I & gt;; = 0 & amp& ampj & gt=0)

If (바둑판 [i-][j-]! = 'X')

0 을 반환합니다

I = locx+1;

J = locy-1;

While (나<8 & amp& ampj & gt=0)

If (바둑판 [i++][j-]! = 'X')

0 을 반환합니다

I = locx-1;

J = locy+1;

While(I & gt;; = 0 & amp& ampj & lt8)

If (바둑판 [i-][j++]! = 'X')

0 을 반환합니다

I = locx+1;

J = locy+1;

While (나<8 & amp& ampj & lt8)

If (바둑판 [i++][j-]! = 'X')

0 을 반환합니다

1;

}

메인 ()/* 마스터 프로그램 */

{

Int I, j;

For(I = 0;; 나<8; I++)

For(j = 0;; J<8; J++)

바둑판 [I] [j] =' x';

N _ queens (0,0,0);

Printf ("체스판에 8 명의 황후의 그래픽. is: n");

For(I = 0;; 나<8; I++)

For(j = 0;; J<8; J++)

{

If (검사기 [i][j] == 'Q')

Printf("(%d, %d)n ",I, j);

}

Getch ();

}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

* * * * * * * * * * * * * * * * 8 황후 * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

* * * * * * * * * * * * 안삼촌이 준 클래스 c 알고리즘에 따라 * * * * * * * * * * * * * * * * * * * * * * * * * * *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

# include & ltstdio.h & gt

# 정의 N 8

Int col= 1, row= 1, slash= 1, blash =1;

Int a [n] [n];

Int p, q, k, l;

Intnum = 0;

유효하지 않은 실험 (int I)

{

Int j;; /* 여기서 j 는 내부 변수 */

다음 경우 (i==N)

{

Num++;+;

For(k = 0;; K & ltn;; K++)

{

For(l = 0;; L & ltn;; L++)

{

If(a[k][l]== 1)

Printf ("@");

Elseprintf ("*");

}

Printf ("n");

}

Printf ("nn");

Getchar ();

}

기타

{

For(j = 0;; J & ltn;; J++)

{

For(k = 0;; K< 나; K++)

If(a[k][j]== 1)

{

Col = 0;;

깨뜨리다

}/* 열 */

P = I-1;

Q = j+1;

While((p & gt;; = 0)& amp;; & amp(q & ltn))

{

If(a[p][q]== 1)

{

슬래시 = 0;

깨뜨리다

}

P-;

Q++;+;

}

P = I-1;

Q = j-1; /* 대각선 */

While((p & gt;; = 0)& amp;; & amp (q & gt=0))

{

If(a[p][q]== 1)

{

B 플래시 = 0;

깨뜨리다

}

P-;

Q-;

}/* 대각선 */

If ((col = =1) & & amp (슬래시 = =1) & & amp (b 플래시 = =1))/* 조건부 판단 */

{

A [I] [j] =1;

시험 (I+1);

}

Col =1; 슬래시 =1; B 플래시 =1;

A [I] [j] = 0;

}

}

}

Void main ()

{

시험 (0);

Printf("%dn ",num);

Getchar ();

}