- [P1219 [USACO1.5]八皇后 Checker Challenge](https://www.luogu.com.cn/problem/P1219)
我在这里想介绍一下如何用dfs解n皇后。
图片来自于:biibii懒猫老师
实现代码如下:
#include<stdio.h>
int place[15];//0表示没放,非0表示放了,并且表示放在第几列,下标表示行数
int flag[15],d1[30],d2[30];//d1为上对角线,d2为下对角线,0表示未被占据,非0表示已占据
int n,count,top;
void dfs(int row)
{
if(row>n)//边界情况要>n,不是等于n
{
count++;
if(count<=3)
{
for(int i=1;i<=n;i++)
{
printf("%d ",place[i]);
}
printf("\n");
}
return;
}
for(int i=1;i<=n;i++)//1至n列,尝试第row个皇后在第row行的不同可能
{
if(!flag[i]&&!d1[row-i+n]&&!d2[row+i])
{
place[row]=i;
flag[i]=1;
d1[row-i+n]=1;
d2[row+i]=1;
dfs(row+1);
//回溯后取消标记
flag[i]=0;
d1[row-i+n]=0;
d2[row+i]=0;
}
}
}
int main()
{
scanf("%d",&n);
dfs(1);
printf("%d",count);
return 0;
}
- [P2404 自然数的拆分问题](https://www.luogu.com.cn/problem/P2404)
这题我同样用dfs解。
所以代码如下:
#include<stdio.h>
int a[10];//存加数
void dfs(int number,int x)//number为第几个加数位置,x为剩下的数
{
if(x==0&&number>2)
{
for(int i=1;i<number-1;i++)//特别注意此时是i<number-1,不是i<number
printf("%d+",a[i]);
printf("%d\n",a[number-1]);
return;
}
for(int i=1;i<=x;i++)//处理节点情况,判断每个位置每个加数的可能性
{
if(i>=a[number-1])//此时a[0]=1发挥作用
{
a[number]=i;
x-=i;
dfs(number+1,x);
//回溯
a[number]=0;
x+=i;
}
}
return;
}
int main()
{
int n=0;
scanf("%d",&n);
a[0]=1;
dfs(1,n);
return 0;
}