N 황후 문제. - 위치 보존 상태 사고.

1386 단어 알고리즘
1. N 황후 문 제 는 무엇 입 니까?
    nxn 의 바둑판 위 에 있 는 모든 황 후 는 서로 공격 할 수 없다. 쉽게 말 하면 모든 황 후 는 같은 줄 에 도 없고 같은 열 에 도 없고 같은 대각선 에 도 없다 는 것 이다.
2. 사고방식
    재 귀 를 이용 하여 각 줄 의 가능 한 황후 위 치 를 한 줄 한 줄 씩 들 고 빈 거 를 하 는 동시에 32 비트 의 정수 로 해당 위치 가 사용 가능 한 지 를 저장 합 니 다. 다음 코드 는 다음 과 같 습 니 다.
        row 현재 행 은 앞의 황후 와 같은 열 로 인해 사용 할 수 없 는 모든 위 치 를 저장 합 니 다.
        ld 는 현재 행 인 이 앞의 황후 와 왼쪽 대각선 으로 인해 사용 할 수 없 는 위 치 를 저장 합 니 다.
        rd 현재 행 인 은 앞의 황후 와 오른쪽 대각선 으로 인해 사용 할 수 없 는 위 치 를 저장 합 니 다.
    마지막 으로 row, ld, rd 위 치 를 현재 줄 의 모든 사용 할 수 없 는 위 치 를 얻 을 수 있 습 니 다. 넘 치 는 원인 을 주의 하 십시오.
    BIT 와 비슷 한 것 은 i & i 로 모든 바 이 너 리 값 p 를 추출 한 다음 에 심층 재 귀 를 하 는 것 입 니 다. row | p 는 자 연 스 럽 게 새로운 row 입 니 다. ld 와 rd 는 | p 이후 에 각각 1 을 좌우 로 이동 하면 됩 니 다. 이전의 넘 침 처 리 는 바로 이곳 의 이동 때 문 입 니 다.
3. 해결 코드
#include 
#include 
#include 
const int n=8; 
long sum = 0, upperlim = (1 << n) - 1;;

void test(long row,long ld,long rd)
{
    if(row!=upperlim){
		long pos=upperlim&~(row|ld|rd);
		while(pos){
			long p=pos&-pos;
	 		pos-=p;
	 		test(row|p,(ld|p)<<1,(rd|p)>> 1);
	  	}
    }
    else sum++;
}

int main(int argc, char *argv[])
{  	
   	time_t tm=time(0);
   	test(0,0,0);
   	printf("%d      %ld   ,    %d  
",n,sum,(int)(time(0)-tm)); return 0; }

좋은 웹페이지 즐겨찾기