难死了,《全球变暖》 蓝桥杯大题 , 写对这一个必有三等奖啊,但是就有人不会写,比如我。

蓝桥杯全球变暖题目链接

首先我得感谢我的易绝顶老师,当初我写这个题目想了1个多星期,与其绞尽脑汁还不如被易绝顶老师骂一顿,哈哈哈哈,感谢易道云的指导。  
        废话不多说啊.
  1.    只要与“.”接触的陆地  就是会淹没。

       #

     ###  

      #  就不会淹没
  2.   数出岛屿的个数。
  那么问题来了!怎么遍历岛屿的个数???   

  遍历一个陆地后 就递归 遍历 它的 上下左右 的位置 ,如果是陆地就做标记。

  u  

l # r

  d  

    我代码里面写的这个 l,u ,r,d  是相对与此时正在被遍历的陆地。   这里一定要理解 不然看不懂代码。

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
int count = 0; 
char map[1000][1000];    // 地图。
char arry[1000][1000];   // 再从新分配另一个一模一样的地图  方便遍历
char size = '1'; // 先用“1” 来标记   一个岛屿, 后面再变化, 用其他的标记另一座岛屿。
int n;     // 这个地图的维度。
_Bool find(char map[][1000], int x, int y) {     
    if (y > n || x > n)     // 这句 判断 是否 超出地图边界。 作为结束递归的条件之一。 
    {
        printf("dfg  ");  
        return 0;
    }
    arry[x][y] = size;   // 如果遍历过就在这里设 “1”。 
    int l, d, r, u;           // Left down right up , 这里是相对于此时的 陆地的 上 下 左 右。 
    l = d = r = u = -1;       // 初始化 为 -1 是避免与后面的 判断冲突。
    if (map[x][y + 1] == '#')  // 判断这个陆地 是否能向右边继续遍历。
    {
        l = 0;
        if (arry[x][y + 1] == '0')  // 如果是1 就表示 已经遍历过了, 0 表示没有遍历过。
        {                            //  进入这个if 表示没有遍历过。
            arry[x][y + 1] = size;
            l = find(map, x, y + 1);     //  向右边继续遍历 ,最后返回的数据      
        }
    }
    if (map[x + 1][y] == '#')  //是否能向下边继续遍历。
    {
        d = 0;
        if (arry[x + 1][y] == '0') {
            arry[x + 1][y] = size;  //  用size 标记这个点被遍历过了。
            d = find(map, x + 1, y);
        }
    }
    if (map[x][y - 1] == '#')   //是否能向左边继续遍历。
    {
        r = 0;
        if (arry[x][y - 1] == '0') {
            arry[x][y - 1] = size;  //  用size 标记这个点被遍历过了。
            r = find(map, x, y - 1);
        }
    }
    if (map[x - 1][y] == '#')    //是否能向上边继续遍历。
    {
        u = 0;
        if (arry[x - 1][y] == '0') {
            arry[x - 1][y] = size;  //  用size 标记这个点被遍历过了。
            u = find(map, x - 1, y);
        }
    }                                                     //                   0
    if (l == 0 && r == 0 && u == 0 && d == 0)   //                           0 # 0   说明此时只有一个 陆地 肯定会被淹没 就没有继续遍历的必要了。 
        return 1;                //                        1                   0                       # 
    if (r == 1 || l == 1 || u == 1 || d == 1)    //      1 # 1    这个if条件 说明 此时的 情况是这样的 ###  则不会被淹没。
        return 1;//                                        1                                           # 
    return 0;
}

int main() {
    memset(arry, '0', 1000000);  // 一模一样的地图 方便检查原地图。
    scanf("%d", &n);            
    for (int x = 0; x < n; x++) {
        scanf("%s", map[x]);      // 这个输入要注意下, 我是直接从 map 的第二位开始输入字符串。 不会的人可以去检查打印出来看看是否输入进去。
    }      
    for (int x = 0; x < n; x++) {
        for (int y = 0; y < n; y++) {
            if (map[x][y] == '#' && arry[x][y] == '0') {   // 先从地图的从来没有被标记过的陆地开始遍历, arry[x][y] == '0'  说明此时的陆地从来没有遍历过。
                if (find(map, x, y) == 0)    // 先从地图的第一个陆地开始遍历,  函数返回0 则说明成功遍历完了一个岛屿, 而且这个岛屿不会淹没。 
                    count++;    //   岛屿个数。

                size += '2' - '1';//标记完了一个岛屿, 后面再变化,用其他的标记另一座岛屿。
            }
        }
    }
    printf("%d", count);
    return 0;
}


 for (int x = 0; x < n; x++) {
        scanf("%s", map[x]);    
    }      

我这里用整行输入的原因 是scanf 输入再匹配格式串的时候,会有空格和没有空格的区别,导致输入有问题,具体可以看 我以前写的文章,   新手使用scanf()最最最最容易遇到的问题,根据自己的经历做点总结 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值