精华内容
下载资源
问答
  • dfs算法经典例题

    千次阅读 2015-07-21 19:23:01
    Oil Deposits #include #include int m,n,sum; ...char map[102][102];...int dir[8][2]= {0,1,0,-1,1,0,-1,0,-1,-1,1,1,-1,1,1,-1};...void dfs(int i,int j) {  for(int s=0; s  {  int di=i+di

    Oil Deposits

    #include<stdio.h>

    #include<string.h>
    int m,n,sum;
    char map[102][102];
    int dir[8][2]= {0,1,0,-1,1,0,-1,0,-1,-1,1,1,-1,1,1,-1};
    void dfs(int i,int j)
    {
        for(int s=0; s<8; s++)
        {
            int di=i+dir[s][0];
            int dj=j+dir[s][1];
            if(di<0||dj<0||di>=m||dj>=n||map[di][dj]=='*')
                continue;
            map[di][dj]='*';
            dfs(di,dj);
        }
    }
    int main()
    {
        while(~scanf("%d%d",&m,&n))
        {
            sum=0;
            for(int i=0; i<m; i++)
                   scanf("%s",map[i]);
            for(int i=0; i<m; i++)
                for(int j=0; j<n; j++)
                    if(map[i][j]=='@')
                    {
                        map[i][j]='*';
                        dfs(i,j);
                        sum++;
                    }
            printf("%d\n",sum);
        }
        return 0;
    }
    展开全文
  • dfs算法-例题油田

    2019-02-23 15:18:45
    个人心得:这是dfs的经典入门题; 全局定义: char map[101][101]; int n, m, sum; 输入流: for (i = 0; i ; i++) //输入流处理 { for (j = 0; j ; j++) { cin >> map[i][j]; } } 然后就是判断...

    Problem Description
    The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid.

    问题描述
    GeoSurvComp地质调查公司负责检测地下石油储量。GeoSurvComp一次与一个大的矩形区域一起工作,并创建一个网格,将土地划分为多个方形图。然后,它使用传感设备分别分析每个图,以确定该图是否含有油。含有油的地块称为口袋。如果两个口袋相邻,则它们是相同油藏的一部分。油沉积物可能非常大并且可能包含许多口袋。您的工作是确定网格中包含多少不同的油藏。

    Input
    The input file contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either *', representing the absence of oil, or@’, representing an oil pocket.

    输入
    输入文件包含一个或多个网格。每个网格都以包含m和n的行开头,即网格中的行数和列数,由单个空格分隔。如果m = 0,则表示输入结束;否则1 <= m <= 100并且1 <= n <= 100.此后是m行,每行n个字符(不计行行尾字符)。每个字符对应一个图,并且是’*’,表示没有油,或’@’,代表一个油口袋。

    Output
    For each grid, output the number of distinct oil deposits. Two different pockets are part of the same oil deposit if they are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets.

    输出
    对于每个网格,输出不同的油藏数量。如果两个不同的口袋水平,垂直或对角相邻,则它们是相同油藏的一部分。油藏不得超过100个口袋。

    Sample Input
    1 1
    *
    3 5
    @@*
    @
    @@*
    1 8
    @@***@
    5 5
    ****@
    @@@
    @**@
    @@@
    @
    @@**@
    0 0

    Sample Output
    0
    1
    2
    2
    个人心得:这是dfs的经典入门题;
    全局定义:

    char map[101][101];
    int n, m, sum;
    

    输入流:

    for (i = 0; i < m; i++)   //输入流处理
    {
    	for (j = 0; j < n; j++)
    	{
    		cin >> map[i][j];
    	}
    } 
    

    然后就是判断一下越界条件,bfs函数里面作用是把有有油田的和它相邻的全部标记为另外的符号

    ac代码:

    #include <iostream>
    #include <stdio.h>
    using namespace std;
    char map[101][101];
    int n, m, sum;
    void dfs(int i, int j)
    {
    	if (map[i][j] != '@' || i < 0 || j < 0 || i >= m || j >= n) return;     //若该点不可行或越界,返回
    	else    //否则,标记该点为不可行,再往8个方向深搜
    	{
    		map[i][j] = '!';
    		dfs(i - 1, j - 1);
    		dfs(i - 1, j);
    		dfs(i - 1, j + 1);
    		dfs(i, j - 1);
    		dfs(i, j + 1);
    		dfs(i + 1, j - 1);
    		dfs(i + 1, j);
    		dfs(i + 1, j + 1);
    	}
    }
    
    int main()
    {
    	int i, j;
    	while (cin >> m >> n)     //输入矩形边长
    	{
    		if (m == 0 || n == 0) break;//越界条件
    		sum = 0;
    		for (i = 0; i < m; i++)   //输入流处理
    		{
    			for (j = 0; j < n; j++)
    			{
    				cin >> map[i][j];
    			}
    		} 
    		for (i = 0; i < m; i++)   //搜索处理
    		{
    			for (j = 0; j < n; j++)
    			{
    				if (map[i][j] == '@')
    				{
    					dfs(i, j);
    					sum++;
    				}
    			}
    		}
    		cout << sum << endl;
    	}
    
    	return 0;
    }
    
    
    展开全文
  • #include #include int m,n,sum; char map[102][102]; int dir[8][2]= {0,1,0,-1,1,0,-1,0,-1,-1,1,1,-1,1,1,-1}; void dfs(int i,int j) { for(int s=0; s; s++) { int di=i+dir[s][0];
    #include<stdio.h>
    
    #include<string.h>
    int m,n,sum;
    char map[102][102];
    int dir[8][2]= {0,1,0,-1,1,0,-1,0,-1,-1,1,1,-1,1,1,-1};
    void dfs(int i,int j)
    {
        for(int s=0; s<8; s++)
        {
            int di=i+dir[s][0];
            int dj=j+dir[s][1];
            if(di<0||dj<0||di>=m||dj>=n||map[di][dj]=='*')
                continue;
            map[di][dj]='*';
            dfs(di,dj);
        }
    }
    int main()
    {
        while(~scanf("%d%d",&m,&n))
        {
            sum=0;
            for(int i=0; i<m; i++)
                   scanf("%s",map[i]);
            for(int i=0; i<m; i++)
                for(int j=0; j<n; j++)
                    if(map[i][j]=='@')
                    {
                        map[i][j]='*';
                        dfs(i,j);
                        sum++;
                    }
            printf("%d\n",sum);
        }
        return 0;
    }

    展开全文
  • 补全等式 下图中,每个方块代表 1…131\ldots131…13 中的某一个数字,但不重复。...这里利用深度优先算法进行搜索 #include<iostream> using namespace std; bool visit[14] = { false }; int arr[12]...

    补全等式

    下图中,每个方块代表 1…131\ldots131…13 中的某一个数字,但不重复。
    在这里插入图片描述
    例如:
    1×2+9×7=13×51 \times 2 + 9 \times 7 = 13 \times 51×2+9×7=13×510×8−12×3=11×410 \times 8 - 12 \times 3 = 11 \times 410×8−12×3=11×4
    只要有任意一个方块代表的数字不同,就算两种不同的方案。
    请你计算,一共有多少种不同的方案。

    这里利用深度优先算法进行搜索

    #include<iostream>
    using namespace std;
    bool visit[14] = { false };
    int arr[12];
    int dfs_count = 0;
    void dfs(int depth)
    {
     if (depth == 6 && arr[0] * arr[1] + arr[2] * arr[3] != arr[4] * arr[5]) return; //二叉树剪枝
     if (depth == 12)//当12个空格全部填满时
     {
      if (arr[6] * arr[7] - arr[8] * arr[9] == arr[10] * arr[11]) dfs_count++; //符合条件,计数器加1
      return;//不符合条件返回
     }
     for (int i = 1; i <= 13; ++i)
     {
      if (!visit[i])
      {
       visit[i] = true;//记录该数字已经被填入
       arr[depth] = i;
       dfs(depth + 1);
       visit[i] = false;//回溯,该数字标记未访问,以便后续填入
      }
     }
    }
    int main()
    {
     dfs(0);
     cout << dfs_count;
     return 0;
    }

    这一题如果不剪枝,直接当depth为12时用函数对数组进行整体判断,会浪费较长的时间,相当于把所有的数字组合全部判断了一遍。

    九宫格

    将数字 1…9填入一个 3×3 的九宫格中,使得格子中每一横行和的值全部相等,每一竖列和的值全部相等。请你计算有多少种填数字的方案。

    #include<iostream>
    using namespace std;
    bool visit[9] = { false };
    int arr[10];
    bool judge(int arr[])
    {
     for (int i = 0; i < 9; i += 3)
     {
      int sum = 0;
      sum = arr[i] + arr[i + 1] + arr[i + 2];
      if (sum != 15) return false;
     }
     for (int i = 0; i < 3; i++)
     {
      int sum = 0;
      sum = arr[i] + arr[i + 3] + arr[i + 6];
      if (sum != 15) return false;
     }
     return true;
    }
    void print(int arr[])
    {
     for (int i = 0; i < 9; ++i)
     {
      cout << arr[i] << ' ';
      if ((i + 1) % 3 == 0) cout << endl;
     }
    }
    void dfs(int arr[], bool visit[],int depth, int& count)
    {
     if (depth == 9)
     {
      if (judge(arr))
      {
       count++;
       print(arr);
      }
      return;
     }
     for (int i = 1; i <= 9; ++i)
     {
      if (!visit[i])
      {
       visit[i] = true;
       arr[depth] = i;
       dfs(arr,visit, depth + 1, count);
       visit[i] = false;
      }
     }
    }
    int main()
    {
     int count=0;
     dfs(arr,visit, 0, count);
     cout << count;
     return 0;
    }

    代码的形参可以改进

    礼物盒

    小y 有一个宽度为 100cm,高度为 20cm,深度为 1cm 的柜子,如下图。
    在这里插入图片描述
    小y 还有 363636 个礼物盒,他们的深度都为 1cm。
    他们对应的宽度和高度如下,单位(cm)。
    在这里插入图片描述
    数据可以参考 礼物盒的数据。
    现在小y 想把这些盒子放到柜子上,由于礼物盒里面都装有礼物,礼物盒必须向上放置,并且不能堆放。由于礼物盒深度和柜子深度一样,所以礼物盒和柜子深度方向也必须一致。并且礼物盒的高度还不能大于柜子的高度,否者放不进去。小y 希望放到柜子上礼物盒的宽度和正好等于柜子的宽度,也就是希望柜子两边都不存在间隙。如下图符合条件的放置。
    在这里插入图片描述
    满足条件的情况下,小y 希望能尽可能多的放置礼物盒,算出最多能放多少个礼物盒。

    这道题目如果用dfs直接暴力搜索的话需要的时间很久很久,做不出来。
    首先我们删除高度高于20的数据,然后将盒子按照宽度非递减的顺序排序,用贪心的方法,从小开始放,第一个符合的盒子数目就是能放下最大的盒子数目。
    以后填空题应该注意做题方法

    #include<iostream>
    #include<algorithm>
    using namespace std;
    int visit[35];
    int wighth[35] = { 11,8,11,16,1,2,6,10,17,10,6,5,2,19,4,5,5,15,3,15,7,11,9,17,9,4,10,12,17,19,20,11,10,20,3 };
    int max_count = -1, depth = 0;
    void dfs(int depth,int sum)
    {
     if (sum == 100) {
      max_count = depth;
      cout << depth << endl;
      return;
     }
     for (int i = 0; i < 35; ++i)
     {
      if (!visit[i]&&!(sum+wighth[i]>100))
      {
       visit[i] = true;
       dfs(depth + 1, sum + wighth[i]);
       visit[i] = false;
      }
     }
    }
    int main()
    {
     sort(wighth, wighth + 35);
     dfs(0, 0);
     return 0;
    }

    全排列(DFS的条件控制,修剪枝叶)

    相信大家都知道什么是全排列,但是今天的全排列比你想象中的难一点。我们要找的是全排列中,排列结果互不相同的个数。比如:aab 的全排列就只有三种,那就是aab,baa,aba。代码框中的代码是一种实现,请分析并填写缺失的代码。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int N=1e3;
    char str[N], buf[N];//buffer
    int vis[N], total, len;
    void arrange(int num) {
        if (num == len){
            printf("%s\n", buf);
            total++;
            return;
        }
     for (int i = 0; i < len; ++i) {
            if (!vis[i]) {
                int j;
                for (j = i + 1; j < len; ++j) {
                    if (/*在这里填写必要的代码*/) {
                        break;
                    }
                }
                if (j == len) {
                    vis[i] = 1;
                    buf[num] = str[i];
                    arrange(num + 1);
                    vis[i] = 0;
                }
            }
        }
    }
    int main() {
        while (~scanf("%s",str)) {
            len = strlen(str);
            sort(str, str + len);
            total = 0;
            buf[len] = '\0';
            arrange(0);
            printf("Total %d\n", total);
        }
        return 0;
    }

    答案:

    str[j] == str[i]&&vis[j]

    这道题目的意思是,假如字符串中有重复的字符,例如aaabbbccc,只能顺序访问其中的重复字母,这样不会产生同样的结果。

    素数个数

    用 0,1,2,3⋯70,1,2,3 \cdots 70,1,2,3⋯7 这 888 个数组成的所有整数中,质数有多少个(每个数字必须用到且只能用一次)。提示:以 000 开始的数字是非法数字。

    #include<iostream>
    #include<algorithm>
    using namespace std;
    int primer_count = 0;
    bool judge(int n)
    {
     for (int i = 2; i*i <= n; ++i)
      if (n%i == 0) return false;
     return true;
    }
    int main()
    {
     int a[8] = { 0,1,2,3,4,5,6,7};
     do {
      if (a[0] == 0||a[7]==0||a[7]==2||a[7]==4||a[7]==6) continue;
      int m=1;
      unsigned long long n = 0;
      for (int i = 7; i >=0; --i,m*=10)
      {
       n += m * a[i];
      }
      if (judge(n))
      {
       //cout << n << endl;
       primer_count++;
      }
     } while (next_permutation(a, a + 8));
     cout << primer_count;
     return 0;
    }

    加减乘

    请对于下面式子进行填空,填入加减乘,使这个表达式成立。
    在这里插入图片描述
    请输出一共有多少种方案可以使得表达式成立。

    这个问题有两个关键的地方,一个是根据深度优先搜索找出所有的符号填充可能,第二是根据符号算出整个表达式的值。

    首先对乘号两边的数进行运算,把最左边的数赋为连乘的结果,其余乘数全赋为-1。
    遇到加号,只需将加号右边的一个值加入结果值,减号同理。

    #include<iostream>
    using namespace std;
    int arr1[10];
    char arr2[9];
    int ans = 0;
    bool caculate(int arr1[], char arr2[])
    {
     for (int i = 0; i < 10; ++i)
      arr1[i] = i+1;
     int i = 0;
     while (i < 9) {
      if (arr2[i] == '*')
      {
       int count = 0, j = i;
       while (arr2[j++] == '*') count++;
       for (int k = 1; k <= count; ++k) {
        arr1[i] *= arr1[i + k];
        arr1[i+k] = -1;
       }
       i += count;
       continue;
      }
      ++i;
     }
     i = 0;
     int sum = arr1[0];
     while (i < 9) {
      if (arr2[i] == '+')
       sum += arr1[i+1];
      if (arr2[i] == '-')
       sum -= arr1[i+1];
      ++i;
     }
     if (sum == 0) return true;
     return false;
    }
    void dfs(int depth)
    {
     if (depth == 9)
     {
      if (caculate(arr1, arr2)) {
       ++ans;
       for (int i = 0; i < 9; ++i)
        cout << arr2[i] << ' ';
       cout << endl;
      }
      return;
     }
     for (int i = 1; i <= 3; ++i)
     {
      switch(i)
      {
      case 1:arr2[depth] = '+'; break;
      case 2:arr2[depth] = '-'; break;
      case 3:arr2[depth] = '*'; break;
      default:break;
      }
      dfs(depth + 1);
     }
    }
    int main()
    {
     dfs(0);
     cout << ans;
     return 0;
    }

    连连看

    连连看是一款非常有意思的游戏。
    在这里插入图片描述
    我们可以把任意两个在图的在边界上的相同的方格一起消掉,比如把两个 444 消掉以后,
    在这里插入图片描述
    每次消掉两个方格的时候,都有会获得一个分数,第 iii 次消的分数为 i×i \timesi× 方格的值。比如上面的消法,是第一次消,获得的分数为 1×4=41 \times 4 = 41×4=4。请你帮忙最优操作情况下,获得的分数最多为多少。

    #include<iostream>
    using namespace std;
    int map[4][4];//记录是否访问,已访问为1,未访问为0
    int value[4][4] = { 1,4,2,5,2,1,2,1,3,1,3,2,2,5,3,4 };
    int visit[4][2] = { {0,1},{0,-1},{1,0},{-1,0} };
    int maxsum = -1;
    bool judge(int x, int y)//判断该块是否是边界
    {
     if (map[x][y]) return false;
     if (x == 0 || x == 3 || y == 0 || y == 3) return true;
     for (int i = 0; i < 4; ++i)
     {
      if (x + visit[i][0] >= 0 && x + visit[i][0] < 4 && y + visit[i][1] >= 0 && y + visit[i][1] < 4)
       if (map[x + visit[i][0]][y + visit[i][1]])
        return true;
     }
     return false;
    }
    void dfs(int depth,int sum)
    {
     if (sum > maxsum)
     {
      maxsum = sum;
      cout << maxsum << endl;
     }
     for (int i = 0; i < 4; ++i)
     {
      for (int j = 0; j < 4; ++j)
      {
       if (judge(i, j))
       {
        int x = i, y = j;
        for(int i=0;i<4;++i)
         for (int j = 0; j < 4; ++j)
         {
          if ((i!=x||j!=y)&&value[i][j]==value[x][y]&&judge(i,j))
          {
           map[i][j] = 1;//进入下一层递归前,消除两个块
           map[x][y] = 1;
           dfs(depth + 1, sum + depth*value[i][j]);
           map[i][j] = 0;//回溯
           map[x][y] = 0;
          }
         }
       }
      }
     }
    }
    int main()
    {
     dfs(1, 0);
     cout << maxsum;
     while (1);
    }

    在这里插入图片描述
    这道题用深度优先搜索的方法,暴力求出最大值。
    从第一个块开始,先判断是否是边界,如果是边界检查边界中是否存在另外一个与其相同的块,如果存在,标记两个块已访问,进入下一层递归。

    引爆炸弹

    在一个 n×mn \times mn×m 的方格地图上,某些方格上放置着炸弹。手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去。
    在这里插入图片描述
    现在为了引爆地图上的所有炸弹,需要手动引爆其中一些炸弹,为了把危险程度降到最低,请算出最少手动引爆多少个炸弹可以把地图上的所有炸弹引爆。
    输入格式
    第一行输两个整数 n,mn,mn,m,用空格隔开。
    接下来 nnn 行,每行输入一个长度为 mmm 的字符串,表示地图信息。0表示没有炸弹,1表示炸弹。
    数据约定:
    对于 60%60%60% 的数据:1≤n,m≤1001 \le n, m \le 1001≤n,m≤100;
    对于 100%100%100% 的数据:1≤n,m≤1000 1 \le n, m \le 10001≤n,m≤1000;
    数据量比较大,不建议用cin输入。
    输出格式
    输出一个整数,表示最少需要手动引爆的炸弹数。
    在这里插入图片描述
    题目链接

    #include<iostream>
    using namespace std;
    int ans = 0;
    int n, m;
    char map[1005][1005];
    int row_bob[1005], col_bob[1005];
    void bob(int x, int y)
    {
     //cout << "bob:" << x << ',' << y << endl;
     map[x][y] = '0';
     if (row_bob[x] == 0) /*如果此行已经引爆则跳过*/{
      row_bob[x] = 1;//先引爆此行,以免引爆同行的炸弹又在该行进行搜索
      for (int i = 0; i < m; ++i)
       if (map[x][i] == '1')
        bob(x, i);
     }
     if (col_bob[y] == 0)/*如果此列已经引爆则跳过*/ {
      col_bob[y] = 1;//先引爆此列,以免引爆同列的炸弹又在该列进行搜索
      for (int i = 0; i < n; ++i)
       if (map[i][y] == '1')
        bob(i, y);
     }
    }
    int main()
    {
     cin >> n >> m;
     for (int i = 0; i < n; ++i)
      cin >> map[i];
     /*bob(0, 3, 6);
     print();*/
     for(int i=0;i<n;++i)
      for (int j = 0; j < m; ++j)
      {
       if (map[i][j] == '1') {
        bob(i, j);
        //cout << endl;
        ++ans;
       }
      }
     cout << ans << endl;
     //while (1);
     return 0;
    }
    

    这道题目时间限制卡得很严,DFS引爆炸弹,引爆炸弹同时引爆与此炸弹同行同列的炸弹,进行递归,要用数组记录每一行每一列是否引爆,如果引爆直接跳过,否则会超时。引爆行和列的过程中有一个关键点,即先记录该行该列已引爆,再引爆该行该列中的炸弹。

    注意,无论如何,一个图中,引爆炸弹的最少数量和引爆炸弹的顺序无关。

    抠图

    蒜头君在做图像处理的项目时,遇到了一个问题。他需要摘取出图片中,某个黑色线框内的图片,现在请你来帮助他完成这一步,把黑色线框外的区域全部变为黑色,即只保留黑色线框内的颜色。
    蒜头君可能同时摘取多个线框,这些线框不会出现相邻,相交,包含关系,因为选择线框太多,所以蒜头君可能把其中一部分的线框少画一条边,所以这种线框是无效的。已知图中除了黑线上的点外,图像中没有纯黑色(即像素为 000 的点)。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    样例输入
    4 5
    1 0 0 0 1
    1 0 1 0 1
    1 0 1 0 1
    1 0 0 0 1
    5 6
    1 1 1 1 1 1
    1 0 1 0 1 1
    1 0 1 0 1 1
    1 0 0 0 1 1
    1 1 1 1 1 1
    10 10
    1 1 1 1 1 1 1 1 1 1
    1 0 0 0 0 0 1 0 1 0
    1 0 0 0 0 0 1 0 1 0
    1 0 0 1 0 0 1 0 0 0
    1 0 0 0 0 0 1 1 1 1
    1 0 0 0 0 0 1 1 1 1
    1 1 1 1 1 1 1 1 1 1
    1 1 1 0 0 0 1 0 0 0
    1 1 1 0 1 0 1 0 1 0
    1 1 1 0 0 0 1 0 0 0
    样例输出
    0 0 0 0 0
    0 0 1 0 0
    0 0 1 0 0
    0 0 0 0 0
    0 0 0 0 0 0
    0 0 0 0 0 0
    0 0 0 0 0 0
    0 0 0 0 0 0
    0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0
    0 0 0 1 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0
    0 0 0 0 1 0 0 0 1 0
    0 0 0 0 0 0 0 0 0 0

    #include<iostream>
    using namespace std;
    int map[501][501];
    int visit[4][2] = { {0,1},{0,-1},{1,0},{-1,0} };
    int n, m;
    void dfs(int x, int y)
    {
     map[x][y] = 0;
     for (int i = 0; i < 4; ++i)
      if (x + visit[i][0] >= 0 && x + visit[i][0] < n&&y + visit[i][1] >= 0 && y + visit[i][1] < m&&map[x + visit[i][0]][y + visit[i][1]] == 1)
       dfs(x + visit[i][0], y + visit[i][1]);
    }
    int main()
    {
     int k;
     cin >> k;
     while (k--)
     {
      cin >> n >> m;
      for (int i = 0; i < n; ++i)
       for (int j = 0; j < m; ++j)
        cin >> map[i][j];
      for (int i = 0; i < n; ++i)
      {
       if (map[i][0] == 1)
        dfs(i, 0);
       if (map[i][m - 1] == 1)
        dfs(i, m - 1);
      }
      for (int i = 0; i < m; ++i)
      {
       if (map[0][i] == 1)
        dfs(0, i);
       if (map[n - 1][i] == 1)
        dfs(0, i);
      }
      for (int i = 0; i < n; ++i)
      {
       for (int j = 0; j < m; ++j)
       {
        if (j == m - 1) printf("%d", map[i][j]);
        else printf("%d ", map[i][j]);
       }
       printf("\n");
      }
     }
     //while (1);
     return 0;
    }
    
    展开全文
  • DFS入门例题 棋盘问题 问题描述: 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放...
  • DFS算法初步

    2021-05-05 23:24:39
    算法DFS(深度优先搜索)入门 作为一个刚刚接触算法竞赛的大一新生,首次发博客的我在此希望能在csdn里面来记录我自己的成长。 DFS:全称是Depth First Search 是在图论题目里面一个重要的算法。 从我这个菜鸟的理解...
  • 算法笔记--DFS例题

    2020-03-04 23:26:35
    DFS(index + 1, sumW + w[index], sumC + c[index]); } int main(){ cin >> n >> V; for(int i = 0; i ; i++) cin >> w[i]; for(int i = 0; i ; i++) cin >> c[i]; DFS(0, 0, 0); cout ; return 0; } ...
  • 搜索DFS算法

    2018-01-26 17:31:11
    dfs(深度搜索法) 1.首先确定深度或搜索终点 2.利用函数递归(适当做回溯) 【缺点:难以找到最优解但占用内存小】 例题1:Oil Deposits 经典连通块问题 ac代码: #include #include #include using ...
  • 回想了一边过程,dfs需要借助空间来实现打印是一个必然,因为dfs在逻辑上就是考虑的从一个点固定不动连续探寻到底再回退探寻的过程,用上述代码打印四个数字的全排列序列可以很好的模拟这个过程  原本应该为 ...
  • 本篇文章结合了网上几位大佬的文章阐述了DFS和BFS的算法原理和相关例题,如有错误请大家不吝赐教 参考以下链接学习DFS和BFS的算法原理: 图解DFS&BFS 对比: DFS 算法 思想: 一直往深处走,直到找到解或者走不...
  • //DFS适用于在确定for的层数(实际不确定)时可用枚举的情况下 #include <bits/stdc++.h> using namespace std; const int maxn=30; //加const的作用是将其设置为常数,如果不加后面还可
  • void dfs(int i) { vis[i]=1; pre[i]=clock1++; for(int j=1;j;j++) { if(a[i][j]==1&&!vis[j]) dfs(j); } post[i]=clock1++; } int main() { cin>>n; cin>>m; for(int i=1;i;i++) { int x,y; cin>>x>>y; a[x][y]=1...
  • 深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次. 深度优先搜索特别适用于那些探索所有的可能性的这些...
  • 经典例题 1、三个有规律的入门级例题...1、DFS–基本入门模板 和 例题 (绝对入门) (最全) 2、一篇文章完全搞懂深度优先搜索(dfs)(含模板以及例题分析) ps:有小伙伴觉得还要大佬的模板/经典题可以私信我补充~ ...

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 352
精华内容 140
关键字:

dfs算法例题