DFS 入门系列

problem_id=1694)bfs入门成功后,继续入dfs的坑,那么先把bfs做过的题用dfs写一遍吧。。。
马的遍历
话说这种题还是bfs好(毕竟快)。。。但为了配合dfs并且不被TLE就人工加一个阈值限制一下吧。。(受题解大佬提醒 阈值在200左右)上代码!

#include <bits/stdc++.h>

#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 <bits/stdc++.h>
#define check(y,x) (x>=0&&y>=0&&y<dy&&x<dx)
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 <bits/stdc++.h>
#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<bits/stdc++.h>
//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 <bits/stdc++.h>

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);
}

}

猜你喜欢

转载自blog.csdn.net/weixin_46127031/article/details/105519191
dfs