⬅ 返回

1、例题

2、方法

2.1、按行枚举

#include<iostream>
using namespace std;
const int N = 20;
int n;
int r[N];//列
int v[N];//对角线y=x+b---> b=y-x+n 
int unv[N];//反对角线 y=-x+b---> b=y+x
int st[N];//st[k]表示第k行放皇后的列数 
 
void dfs(int x)//找第x行的元素 
{
	if(x>n){//输出 
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(st[i]==j){
					cout<<"Q";
				}else{
					cout<<".";
				}
			}
			cout<<endl;
		}
		cout<<endl;
	}
	//当前是第x行 
	for(int i=1;i<=n;i++)//找列 
	{
		// 剪枝(对于不满足要求的点,不再继续往下搜索)  
		if(r[i]==0 &&v[i-x+n]==0&&unv[i+x]==0)
		{
			st[x]=i;
			r[i]=1;//第i列不让放了 
			v[i-x+n]=1;
			unv[i+x]=1;
			dfs(x+1);
			//恢复现场
			st[x]=0;
			r[i]=0;//第i列不让放了 
			v[i-x+n]=0;
			unv[i+x]=0;
		}
	}	
}
 
int main(){
	cin>>n;
	dfs(1); 
 
}

2.2、按元素枚举

#include <iostream>
using namespace std;
const int N = 20;
 
int n;
char g[N][N];
bool row[N], col[N], dg[N], udg[N];
 
void dfs(int x, int y, int s) // x表示的行 y表示的是列 s表示的是已经放上的皇后个数
{
    if (y == n)
        y = 0, x++; //列超出边界 让行下移 列从0开始
    if (x == n)     //已遍历完所有的行
    {
        if (s == n) //放上了n个皇后
        {
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    cout << g[i][j];
                }
                cout << endl;
            }
            cout<<endl;
        }
        return;
    }
 
    //选择不放
    dfs(x, y + 1, s);
    //选择放上元素
    if (row[x] == false && col[y] == false && dg[x + y] == false && udg[x - y + n] == false)
    {
        g[x][y] = 'Q';
        row[x] = col[y] = dg[x + y] = udg[x - y + n] = true;
        dfs(x, y + 1, s + 1);
        row[x] = col[y] = dg[x + y] = udg[x - y + n] = false;
        g[x][y] = '.';
    }
}
 
int main()
{
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            g[i][j] = '.';
        }
    }
    dfs(0, 0, 0);
 
    return 0;
}