1. 程式人生 > >HDU2553 N皇后問題(回溯法)

HDU2553 N皇后問題(回溯法)

此題是經典的N皇后問題,描述:在一個N*N的棋盤上要擺放N個皇后,要求任意兩個皇后不能在同一行,同一列或者同一條與棋盤的邊成45度角的斜線上,即與對角線平行的斜線上,求對於不同的N,各有多少種擺法使任意兩個皇后不能相互攻擊。

用回溯法就可以解決,設皇后的編號依次為1,2,……,n,則可以認為第i個皇后必須擺放在第i行,然後列舉第一個皇后的位置進行回溯,若某一次發現某個皇后無法找到擺放位置則直接返回,如果所有皇后都可以找到擺放位置,則說明存在一種擺法滿足要求,統計有多少種擺法即可。

此題n<=10,測試資料中會有大量重複資料,因此要儲存答案,遇到曾經計算過的n直接輸出即可,否則可能會超時。

#include<iostream>
using namespace std;
int n;
int x[100];
int ans[11];
bool Place(int k)
{
	int i = 1;
	while (i<k)
	{
		if (x[i]==x[k] || abs(x[i]-x[k])==abs(i-k))	return false;
		i++;
	}
	return true;
}
int main()
{
	int k, cnt;
	memset(ans, 0, sizeof(ans));
	while (scanf("%d", &n)!=EOF && n!=0)
	{
		if (ans[n]>0) 
		{
			printf("%d\n", ans[n]);
			continue;
		}
		x[1] = 0;
		k = 1, cnt = 0;
		while (k>0)
		{
			x[k]++;
			while (x[k]<=n && !Place(k))
			{
				x[k]++;
			}
			if (x[k]<=n)
			{
				if (k==n)
				{
					cnt++;
				}
				else 
				{
					k++;
					x[k] = 0;
				}
			}
			else k--;
		}
		ans[n] = cnt;
		printf("%d\n", cnt);
	}
	return 0;
}