计蒜客蓝桥杯模拟赛5 引爆炸弹

题目
在一个 n×m 的方格地图上,某些方格上放置着炸弹。手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去。

现在为了引爆地图上的所有炸弹,需要手动引爆其中一些炸弹,为了把危险程度降到最低,请算出最少手动引爆多少个炸弹可以把地图上的所有炸弹引爆。
输入格式
第一行输两个整数 n, m,用空格隔开。
接下来 n 行,每行输入一个长度为 m 的字符串,表示地图信息。0表示没有炸弹,1表示炸弹。
数据约定:
对于60% 的数据: 1≤n,m≤100;
对于 100% 的数据: 1≤n,m≤1000;
数据量比较大,不建议用cin输入。
输出格式
输出一个整数,表示最少需要手动引爆的炸弹数。

思路:将所以的炸弹放入一个数组中,然后对其中一个炸弹用dfs()进行连锁引爆,判断是否有还有未被引爆的,如果存在,这引爆数目加一,把当前的引爆,一直这样判断下去。

#include
#include

using namespace std;

struct Point{
    int x; 
    int y;
    int bo;//是否引爆 
};

int n,m,x = 0;
Point p[100];//存放炸弹

void DFS(Point boom,int k)
{
    for(int i = 0;i < x; i++)
    {
        if(i!=k&&p[i].bo==1&&(boom.x==p[i].x||boom.y==p[i].y)) 
        //如果未被引爆且行数或者列数等于其中的一个炸弹
        {
            p[i].bo = 0;//设置为已经爆炸了 
            DFS(p[i],i);
        }
    }
}

int main()
{
    cin >> n >> m;
    int num = 0;
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            int tmp;
            scanf("%1d",&tmp);
            if(tmp)
            {
                p[x].x = i;
                p[x].y = j;
                p[x].bo = 1;
                x++;
            }
        }
    }
    for(int i = 0; i < x; i++)
    {
        if(p[i].bo)
        {
            num++;//需要引爆数目加一
            DFS(p[i],i);
        }
    }
    cout << num;
    return 0;
} 

你可能感兴趣的:(蓝桥杯)