P1219
八皇后问题,每填上一个,都会有对应的不能填,然后数学发现,左斜对角线和相同,那么减去这个行,就很自然得到列,右斜减相同,可能会越界,所以向右移动n,分别用两个数组存放,行号对应的不可以是那个就想象成一个一维数组,每一次都有对应的一个被填上,深搜行号就可以了
#include<iostream>
using namespace std;
int n,cnt;
bool lie[20];//列
bool u[20];//左上到右下
bool v[40];//右上到左下
int a[20];
void pr()
{
if(cnt<=3)
{
for(int i=1;i<=n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
}
void dst(int x)
{
if(x>n)
{
cnt++;
pr();
return;
}
for(int i=1;i<=n;i++)
{
if(!lie[i]&&!u[x-i+n]&&!v[x+i])
{
lie[i]=1;
u[x-i+n]=1;
v[x+i]=1;
a[x]=i;
dst(x+1);
lie[i]=0;
u[x-i+n]=0;
v[x+i]=0;
}
}
}
int main()
{
cin>>n;
dst(1);
cout<<cnt;
}
P1443
不需要回溯的深搜,每一次记录下来数字和总和
P1605
#include<iostream>
using namespace std;
int xx[]={-1,0,1,0};
int yy[]={0,1,0,-1};//打方向
bool mp[100][100]={0}; //判断来没来过
bool qia[100][100]={0};//判断障碍
int c,k,za,qix,qiy,zhx,zhy,a,cnt=0,b,dx,dy,x,y;
void dfs(int x,int y)
{
if(x==zhx&&y==zhy)
{
cnt++;
return;
}
for(int i=0;i<4;i++)
{
int dx=x+xx[i];这个变量要定义在函数里,不要开在堆里,不然就每次都被覆盖
int dy=y+yy[i];
if(!mp[dx][dy]&&dx<=c&&dx>=1&&dy<=k&&dy>=1&&!qia[dx][dy])
{
mp[dx][dy]=1;
dfs(dx,dy);
mp[dx][dy]=0;//回溯
}
}
}
int main()
{
cin>>c>>k>>za;
cin>>qix>>qiy>>zhx>>zhy;
for(int i=1;i<=za;i++)
{
cin>>a>>b;
qia[a][b]=1;
}
mp[qix][qiy]=1;
dfs(qix,qiy);
cout<<cnt;
}
``P1101
其实就是个搜索,定义好八个方向,然后每一次长度即时在这个方向上*长度走起
```cpp
#include<iostream>
using namespace std;
int m;
int p=1,flag;
char a[1100][1100];
int xx[]={-1,-1,-1,0,0,1,1,1};
int yy[]={-1,0,1,1,-1,1,0,-1};
int vis[1100][1100]={0};
string yz="yizhong";
void dfs(int x,int y)
{
for(int i=0;i<8;i++)
{ int flag=1;
for(int j=0;j<7;j++)
{
int dx=x+xx[i]*j;
int dy=y+yy[i]*j;
if(yz[j]!=a[dx][dy]||!(dx>=1&&dx<=m&&dy>=1&&dy<=m))//这是不满足的条件
{flag=0;
break;
}
}
if(flag)
{
for(int j=0;j<7;j++)
{
int dx=x+xx[i]*j;
int dy=y+yy[i]*j;
vis[dx][dy]=1;
}
}
}
}
int main()
{
cin>>m;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]=='y')
dfs(i,j);
}
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=m;j++)
{
if(!vis[i][j])
cout<<"*";
else
cout<<a[i][j];
}
cout<<endl;
}
return 0;
}
放一个模板
#include<iostream>
#include<cmath>
using namespace std;
int p[10]={0};
bool vis[10]={0};
int n;
void dfs(int x)
{
if (x==n+1)
{
for(int i=1;i<=n;i++)
cout<<p[i]<<" ";
cout<<endl;
return ;
}
for (int i=1;i<=n;i++)
{
if (vis[i]==false )
{
p[x] = i;
vis[i] = true;
dfs(x+1);
vis[i] = false;
}
}
}
int main()
{
while (cin>>n)
{
dfs(1);
}
return 0;
}
还有更高级的,等把题目写了再说
就是从开头进入然后深搜,遇到了满足条件的,就从它继续搜下去,记得回溯