problem_id=1694)bfs入门成功后,继续入dfs的坑,那么先把bfs做过的题用dfs写一遍吧。。。
马的遍历
话说这种题还是bfs好(毕竟快)。。。但为了配合dfs并且不被TLE就人工加一个阈值限制一下吧。。(受题解大佬提醒 阈值在200左右)上代码!
#include
#define CHECK(y,x) (x>=1&&x<=wx&&y>=1&&y<=wy)
using namespace std;
int map1[405][405];
int wx,wy;
struct node{
int x,y;};
int dir[8][2]={
{
1,2},{
1,-2},{
2,1},{
2,-1},{
-1,2},{
-1,-2},{
-2,1},{
-2,-1}};//标记马行走方位。
void dfs(int y,int x,int num){
if (num>200) return;
map1[y][x]=num;
for(int i=0;i<8;i++)
{
int nx=x+dir[i][0];
int ny=y+dir[i][1];
if((map1[ny][nx]==-1||map1[ny][nx]>num+1)&&CHECK(ny,nx)){
dfs(ny,nx,num+1);}
}
}
int main()
{
int x,y;
cin>>wy>>wx>>y>>x;//wy是行数,wx是列数。
memset(map1,-1,sizeof(map1));
dfs(y,x,0);
for(int i=1;i<=wy;i++)
for(int j=1;j<=wx;j++)
j!=wx?printf("%-5d",map1[i][j]):printf("%-5d\n",map1[i][j]);
return 0;
}
oj 最大黑色区域
#include
#define check(y,x) (x>=0&&y>=0&&y
using namespace std;
bool _map[105][105];
int dx,dy,num;
int dir[4][2]={
{
1,0},{
0,1},{
-1,0},{
0,-1}};
int dfs(int y,int x)
{
int ny,nx;
_map[y][x]=0;//注意!!!
//这里的第一个位置要及时处理,不然max=1时会wa。。
num++;//将数据提前进行处理,不要放到if中再处理!!
for(int i=0;i<4;i++)
{
nx=x+dir[i][0];ny=y+dir[i][1];
if(check(ny,nx)&&_map[ny][nx]==1)
{
dfs(ny,nx);
}
}
return num;
}
int main()
{
int ans;
while(~scanf("%d %d",&dy,&dx))
{
ans=0;
for(int i=0;i<dy;i++)
for(int j=0;j<dx;j++)
scanf("%d",&_map[i][j]);
for(int i=0;i<dy;i++)
for(int j=0;j<dx;j++)
if(_map[i][j])
{
num=0;
ans=max(dfs(i,j),ans);
}
cout<<ans<<endl;
}
return 0;
}
好久没更新了。。今天继续更一道dfs
需要用到回溯技巧
洛谷 1605 迷宫
#include
#define check(y,x) (x>=1&&x<=b&&y>=1&&y<=a)//定义好边界,进行判断。
using namespace std;
int dir[4][2]={
{
1,0},{
0,1},{
0,-1},{
-1,0}};
int dx,dy,num,px,py,a,b;
bool map1[23][23];
void dfs(int py,int px){
int nx,ny;
if(px==dx&&py==dy){
num++; return;}
for(int i=0;i<4;i++){
ny=py+dir[i][0];
nx=px+dir[i][1];
if(check(ny,nx)&&map1[ny][nx]==0){
map1[ny][nx]=1;//回溯过程!
dfs(ny,nx);
map1[ny][nx]=0;
}
}
return ;
}
int main(){
int n;
scanf("%d %d %d",&a,&b,&n);
scanf("%d %d %d %d",&py,&px,&dy,&dx);
memset(map1,0,sizeof(map1));
for(int i=0;i<n;i++){
int x,y;
scanf("%d %d",&y,&x);
map1[y][x]=1;
}
num=0;map1[py][px]=1;
dfs(py,px);
printf("%d\n",num);
return 0;
}
好久没写dfs了,来更一篇dfs+高精加+斐波拉契数列
洛谷 1225 数楼梯
#include
//dfs+高精加
using namespace std;
int n,len=1,f[5003][5003];//f[k][i]--第k阶台阶所对应的走法数
void hp(int k)//高精度加法,k来存阶数
{
int i;
for(i=1;i<=len;i++)
f[k][i]=f[k-1][i]+f[k-2][i];//斐波拉契数列
for(i=1;i<=len;i++) //高精模板
if(f[k][i]>=10)
{
f[k][i+1]+=f[k][i]/10;
f[k][i]=f[k][i]%10;
if(f[k][len+1])len++;
}
}
int main()
{
int i;
scanf("%d",&n);
f[1][1]=1; f[2][1]=2;
for(i=3;i<=n;i++)
hp(i);
for(i=len;i>=1;i--)
printf("%d",f[n][i]);
return 0;
}
刚刚写了个stl解决排列的方法,现在再更一道用dfs写组合的问题。
洛谷 1157
#include
using namespace std;
bool vis[25];
int m,n;
int a[25];
void dfs(int x,int num){
//用num记录位数,x记录末尾数。
if(num==n){
for(int j=0;j<n-1;j++)
printf("%3d",a[j]);
printf("%3d\n",a[n-1]);
return;}
for(int i=x;i<m+1;i++){
if(!vis[i]){
vis[i]=1;
a[num++]=i;
dfs(i+1,num);
num--;//回溯时注意减一
vis[i]=0;//回溯!
}
}}
int main(){
while(~scanf("%d %d",&m,&n)){
if(!n)return 0;//第10组数据卡0,需要特殊处理!
dfs(1,0);
}
}