ICPC North Central NA Contest GSheba's Amoebas(dfs)

After a successful Kickstarter campaign, Sheba Arriba has raised enough money for her mail-order biology supply company. “Sheba’s Amoebas” can ship Petri dishes already populated with a colony of those tiny one-celled organisms. However, Sheba needs to be able to verify the number of amoebas her company sends out. For each dish she has a black-and-white image that has been pre-processed to show each amoeba as a simple closed loop of black pixels. (A loop is a minimal set of black pixels in which each pixel is adjacent to exactly two other pixels in the set; adjacent means sharing an edge or corner of a pixel.) All black pixels in the image belong to some loop.Sheba would like you to write a program that counts the closed loops in a rectangular array of black and white pixels. No two closed loops in the image touch or overlap. One particularly nasty species of cannibalistic amoeba is known to surround and engulf its neighbors; consequently there may be amoebas within amoebas. For instance, each of the images in figure below contains four amoebas.
在这里插入图片描述
Input
The first line of input contains two integers mmm and nnn, (1≤m,n≤100)(1≤m,n≤100)(1≤m,n≤100). This is followed by mmm lines, each containing nnn characters. A ‘#’ denotes a black pixel, a ‘.’ denotes a white pixel. For every black pixel, exactly two of its eight neighbors are also black.
\[20pt]Output\normalsize \textbf{Output}Output
Display a single integer representing the number of loops in the input.
输出时每行末尾的多余空格,不影响答案正确性 样例输入1 复制 12 12
.##########.
#…#
#…#…##…#
#.##…#…#.#
#…#.#.#
#…#…#…#
#…#.#…#
#…#…#…#
.#…#.#…#
#…#…#
#…#.
.#########… 样例输出1 复制 4 样例输入2 复制 12 10
.#####…
#…#…
#…#…#…
#.#.#.#…
#…#…#…
.#…#…
…###…
…#…
.##…#.#…
#…#…#…
.##…
… 样例输出2 复制 4

标记起始点,然后循环找到起始点,并将路径上的#全部变成.避免重复搜索。

#include <iostream>
#include <queue>

using namespace std;

char map[105][105];
int m,n,ans,fx,fy,cnt,def[110][110];
int dir[8][2] = {{0,1},{0,-1},{1,0},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};//方向

void dfs(int x,int y,int t)
{
    cnt++;
  //  def[x][y] = cnt;
    int xx,yy;
    if(x == fx&&y == fy&&t > 0){//判环,且避免第一次判断时发生误判
            ans++;
            return ;
        }
    for(int i = 0; i < 8; i++){
        xx = x + dir[i][0];
        yy = y + dir[i][1];
  /*    if(def[xx][yy]==1)
            ans++;*/
        if(xx >= 0&&xx < m&&yy >= 0&&yy < n&&map[xx][yy] == '#'){
            map[xx][yy] = '.';
            dfs(xx,yy,t + 1);
        }
    }
}

int main()
{
    cin>>m>>n;
    for(int i = 0; i < m; i++){
        cin>>map[i];
    }
    for(int i = 0; i < m; i++){

        for(int j = 0; j < n; j++){
            if(map[i][j] == '#'){
                fx = i;
                fy = j;
          //      cnt = 0;
                dfs(i,j,0);
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

忽然发现之前有个错误代码,只是ans++的位置写的不太一样,wa了,但是想不明白为什么错了,这里把代码贴出来,望有大神指正我这个弱鸡。

#include <iostream>
#include <queue>

using namespace std;

char map[105][105];//地图;
int m,n,ans,fx,fy;
int dir[8][2] = {{0,1},{0,-1},{1,0},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};//8个方向;

void dfs(int x,int y)
{
    int xx,yy;
    for(int i = 0; i < 8; i++){//当前点所有移动的可能;
        xx = x + dir[i][0];
        yy = y + dir[i][1];
        if(xx == fx&&yy == fy){//如果在某次移动后,回到循环起始点,计数器加1;
            ans++;
            map[xx][yy] = '.';//将该点清除,表示该点已被走过,下同;
        }
        if(xx >= 0&&xx < m&&yy >= 0&&yy < n&&map[xx][yy] == '#'){//如果没有回到起始点且
            map[xx][yy] = '.';                                   //满足可移动条件,就继续走;
            dfs(xx,yy);
        }
    }
}

int main()
{
    cin>>m>>n;
    for(int i = 0; i < m; i++){
        cin>>map[i];
    }//输入地图:
    for(int i = 0; i < m; i++){

        for(int j = 0; j < n; j++){
            if(map[i][j] == '#'){//寻找环的起点;
                fx = i;
                fy = j;//标注搜索起始点;
                dfs(i,j);
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

Cu1
发布了30 篇原创文章 · 获赞 2 · 访问量 946

猜你喜欢

转载自blog.csdn.net/CUCUC1/article/details/105247378