• 洛谷试题 Lake Counting S


    洛谷试题 -Lake Counting S

    https://www.luogu.com.cn/problem/P1596

    这是一道经典的搜索题,其实就是求其中连通块的数目。

    既可以用深搜,又能用广搜。

    下面放广搜代码。

    #include <iostream>
    #include<queue>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int fx[8] = { 0,0,1,1,-1,-1,1,-1 };
    int fy[8] = { 1,-1,1,-1,1,-1,0,0 };//8个方向
    int total = 0;
    char gr[1000][1000];//输入.和w
    int vis[1000][1000], n, m;//vis是判断有没有走过
    struct MS
    {
        int x;
        int y;
    }T1,T2;//结构体 储存点的位置
    queue<MS>q;//广搜之必备队列
    void bfs(int x1, int y1)
    {
      
        T1.x = x1, T1.y = y1;
        q.push(T1);
        while (!q.empty())
        {
            T2 = q.front();
            q.pop();
            for (int i = 0; i < 8; i++)
            {
                if (!vis[T2.x + fx[i]][T2.y + fy[i]] && gr[T2.x + fx[i]][T2.y + fy[i]] == 'W')//如果点没有走过并且点为‘W’,我们就可以把他放入队列并且标记已经走过
                {
                    T1.x = T2.x + fx[i], T1.y = T2.y + fy[i];
                    vis[T2.x + fx[i]][T2.y + fy[i]] = 1;
                    q.push(T1);
                }
            }
        }
    }
    int main()
    {
        memset(vis, 0, sizeof(vis));//将vis初始化为0;
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                cin >> gr[i][j];
            }
        }
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                if (!vis[i][j] && gr[i][j] == 'W')//如果点(i,j)没有走过并且点(i,j)=='w',我们就标记点(i,j)为1,然后广搜,连通块的数目+1;
                {
                    vis[i][j] = 1;
                    bfs(i, j);
                    total++;
                }
            }
        }
        cout << total;//输出连通块的数目
        return 0;
    }
    
    

    下面是深搜代码

    #include<iostream>
    #include<cstring>
    using namespace std;
    char GR[1000][1000];
    bool vis[1000][1000];
    int n, m;
    int total = 0;
    int fx[8] = { 0,0,1,-1,1,1,-1,-1 };
    int fy[8] = { 1,-1,0,0,1,-1,1,-1 };//跟广搜一样,需要八个方向
    void dfs(int x,int y)
    {
    	for (int i = 0; i < 8; i++)
    	{
    		if (!vis[x + fx[i]][y + fy[i]]&& GR[x + fx[i]][y + fy[i]]=='W')//如果点没有走过并且点为'w',我们就标记点为1,表示已经走过,然后搜索与这个点相邻并且没有标记且为w的点。
    		{
    			vis[x + fx[i]][y + fy[i]] = 1;
    			dfs(x + fx[i], y + fy[i]);
    		}
    
    	}
    }
    int main()
    {
    	memset(vis, 0, sizeof(vis));
    	cin >> n >> m;
    	for (int i = 1; i <= n; i++)
    	{
    		for (int j = 1; j <= m; j++)
    		{
    			cin >> GR[i][j];
    		}
    	}
    	for (int i = 1; i <= n; i++)
    	{
    		for (int j = 1; j <= m; j++)
    		{
    			if (GR[i][j] == 'W'&&!vis[i][j])//与广搜同理
    			{
    				vis[i][j] = 1;
    				dfs(i, j);
    				total++;
    			}
    		}
    	}
    	cout << total;
    }
    
  • 相关阅读:
    Activity 生命周期 返回键 退出 杂谈
    多线程基本语法
    常用代码
    JSP 相关
    powerDesiger uml class
    抽象类的说明
    javaScript 中常用的正则表达式
    chickbox 的使用
    对象在内存中的状态
    jQuery 常用代码
  • 原文地址:https://www.cnblogs.com/a821403286/p/13620749.html
Copyright © 2020-2023  润新知