SmartCirno @ 2024-05-22 13:49:41
#include <iostream>
using namespace std;
int n,ans,m[14][14];
bool check(int x,int y) // 判断m[x][y]是否能放
{
for(int i=1;i<=n;i++)if(m[i][y]==1&&i!=x)return false; // 列
for(int j=1;j<=n;j++)if(m[x][j]==1&&j!=y)return false; // 行
for(int i=x,j=y;i>0&&j<=n;i--,j++)if(m[i][j]==1&&(i!=x&&j!=y))return false; // 右上对角线
for(int i=x,j=y;i<=n&&j<=n;i++,j++)if(m[i][j]==1&&(i!=x&&j!=y))return false; // 右下对角线
for(int i=x,j=y;i>0&&j>0;i--,j--)if(m[i][j]==1&&(i!=x&&j!=y))return false; // 左上对角线
for(int i=x,j=y;i<=n&&j>0;i++,j--)if(m[i][j]==1&&(i!=x&&j!=y))return false; // 左下对角线
return true;
}
void output_m()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cout<<m[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
void dfs(int a,int s)
{
if(s==n)
{
//output_m();
ans++;
if(ans>3)return;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(m[i][j])
{
cout<<j<<" ";
break;
}
}
}
cout<<endl;
return;
}
for(int j=1;j<=n;j++)
{
if(check(a,j))
{
m[a][j]=1;
dfs(a+1,s+1);
m[a][j]=0;
}
}
}
int main()
{
cin>>n;
dfs(1,0);
cout<<ans;
return 0;
}
by lovely_codecat @ 2024-05-22 14:06:31
把所有endl改成'\n'即可
by SmartCirno @ 2024-05-22 14:11:42
@lovely_codecat 负优化
by CuteChat @ 2024-05-22 14:26:14
没有必要这么写 check
,记录四个数组(哈希表)
by thehanged @ 2024-06-05 18:40:38
主要是判断对角线的问题
我的做法是正对角线映射的下标是x + i
,反对角线是n + x - i
ac代码
#include <iostream>
#include <vector>
using namespace std;
const int N = 20;
bool col[N], dg[2 * N], udg[2 * N];
vector<int> path;
int n, cnt;
/// 枚举每行,搜索皇后可以放在哪列
void dfs(int x){
if(x == n + 1){
if(cnt < 3){
for(auto& i : path){
cout << i << " ";
}
cout << endl;
}
cnt ++;
return ;
}
for(int i = 1; i <= n; ++ i){
if(col[i] || dg[x + i] || udg[n + x - i]) continue;
col[i] = dg[x + i] = udg[n + x - i] = true;
path.push_back(i);
dfs(x + 1);
path.pop_back();
col[i] = dg[x + i] = udg[n + x - i] = false;
}
}
int main(){
cin >> n;
dfs(1);
cout << cnt << endl;
}