nyoj-最大岛屿

最大岛屿

时间限制: 1000  ms  |  内存限制: 65535  KB
难度: 2
描述

神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等。加勒比海盗,你知道吧?杰克船长驾驶着自己的的战船黑珍珠1号要征服各个海岛的海盜,最后成为海盗王。  这是一个由海洋、岛屿和海盗组成的危险世界。面对危险重重的海洋与诡谲的对手,如何凭借智慧与运气,建立起一个强大的海盗帝国。

杰克船长手头有一张整个海域的海图,上面密密麻麻分布着各个海屿的位置及面积。他想尽快知道整个海域共有多少岛屿以及最大岛屿的面积

输入
第1行:M N T,表示海域的长,宽及一个单位表示的面积大小
接下来有M行 ,每行有N个01组成的序列以及其中穿插一些空格。0表示海水,1表示陆地,其中的空格没用,可以忽略掉。

输出
输出一行,有2个整数,一个空格间隔,表示整个海域的岛屿数,以及最大岛屿的面积
样例输入
8 16 99
00000000 00000000
0000110011000000
0001111000111000
0000000  00 0000000
00111  111000001  10
001110000  0000000
0100001111 111100
0000000000000000
样例输出
5 990
提示
①若一个陆地八个方向之一(上、下、左、右、左上、右上、左下、右下)的位置也是陆地,则视为同一个岛屿。
② 假设第一行,最后一行,第一列,最后一列全为0.
③ 1<M, N≤500 1<T≤100000
   这题一般  不算很难  不过有几个注意点  我也纠结了很长时间

首先是  输入问题    
#include<stdio.h>
int m,n,t;
char map[505][505];
int main()
{
    scanf("%d%d%d",&m,&n,&t);
    int i,j;
    for( i=0; i<m; i++)
    {
        for( j=0; j<n; j++)
        {
            scanf("%c",&map[i][j]);
            if(map[i][j]==' ')
            {
                j--;
            }
        }
    }
    for( i=0; i<m; i++)
    {
        for( j=0; j<n; j++)
        {
            printf("%c",map[i][j]);
        }
        printf("\n");
    }
}

这个输入是有毛病的,输入后  输出的不再是矩形
可以明显的看出  输出的第一行只有15个,不足16
改一下
#include<stdio.h>
int m,n,t;
char map[505][505];
int main()
{
    scanf("%d%d%d",&m,&n,&t);
    int i,j;
    for( i=0; i<m; i++)
    {
        for( j=0; j<n; j++)
        {
            scanf(" %c",&map[i][j]);
            if(map[i][j]==' ')
            {
                j--;
            }
        }
    }
    for( i=0; i<m; i++)
    {
        for( j=0; j<n; j++)
        {
            printf("%c",map[i][j]);
        }
        printf("\n");
    }
}
OK  !!!哪出问题了??
scanf(" %c",&map[i][j]);
对  就是这一小步
%c前面加了一个空格  不加 就不对
具体原因;
输入字符 的话  空格也是字符的一种
%c前面加一个空格的话 可以吸收空格   getchar();
也可以!!!
还有一个  sscanf  可以去空格输出,以前都不知道!!
学到了!!

还有就是
getchar();
的位置非常讲究
正确的位置如下
#include<stdio.h>
int m,n,t,max,s,z;
char map[505][505];
}
int main()
{
    scanf("%d%d%d",&m,&n,&t);
    max=0,s=0;
    int i,j;
    for( i=0; i<m; i++)
    {
        getchar();
        for( j=0; j<n; j++)
        {
            scanf(" %c",&map[i][j]);
            if(map[i][j]==' ')
            {
                j--;
            }
        }
    }
    printf("\n");
    for( i=0; i<m; i++)
    {
        for( j=0; j<n; j++)
        {
            printf("%c",map[i][j]);
        }
        printf("\n");
    }
}
应该加在两个for循环中间
我加在第二个后面就不对
因为我是  输完一行后才换行的
加在第一个;
如果加在第一个表示我输入一个换一行  

下面就好弄了
   
#include<stdio.h>
int m,n,t,max,s;
char map[505][505];
int dir[8][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
void dfs(int x,int y,int z)
{
    if(z>max)
    {
        max=z;
    }
    //printf("%d %d %d %d$\n",x,y,max,s);
    for(int i=0;i<8;i++)
    {
        //printf("%d %d %d***\n",dx,dy,z);
        int dx=x+dir[i][0];
        int dy=y+dir[i][1];
        if(dx>=0&&dy>=0&&dx<n&&dy<m&&map[dx][dy]=='1')
        {
            printf("%d %d %d*\n",dx,dy,z);
            map[dx][dy]='0';
            dfs(dx,dy,z+1);
        }
    }
}
int main()
{
    while(scanf("%d%d%d",&m,&n,&t)!=EOF)
    {
        max=0,s=0;
        int i,j;
        for( i=0; i<m; i++)
        {
            for( j=0; j<n; j++)
            {
                scanf(" %c",&map[i][j]);
                if(map[i][j]==' ')
                {
                    j--;
                }
            }
        }
        printf("\n");
        for( i=0; i<m; i++)
        {
            for( j=0; j<n; j++)
            {
                printf("%c",map[i][j]);
            }
            printf("\n");
        }
        for( i=0; i<m; i++)
        {
            for( j=0; j<n; j++)
            {
                if(map[i][j]=='1')
                {
                    s++;
                    dfs(i,j,0);
                }
            }
        }
        printf("%d %d\n",max*t,s);
        printf("%d %d\n",s,max*t);
    }
}


结果不对,好了  日常dbug时间!!!
错因,有的岛按多个算了  
岛的数量多了,面积小了
岛的数量多了  是因为
dx<n&&dy<m
错了  应该是  dx<m&&dy<m
不知道为何 我总是判反
下面总结一下为何会判反
在找1的两个for循环中
i表示的是列,j表示的是行
而我dfs的时候直接dfs(i,j);
还以为输入的是 dfs(x,y);
其实是  dfs(y,x);  
那么我判定的时候就要反过来了
其实判定是没错  别的地方有错。

还有计算面积我用的计算步数的方法  
那是错误的
找步数的原理是  我如果回溯的话  步数要减一
而找岛大小不用
我既然递归到这里了  
那说明这就是岛的一部分 
回溯的时候不用再减一了
AC代码
#include<stdio.h>
int m,n,t,max,s,z;
char map[505][505];
int dir[8][2]= {{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
void dfs(int x,int y)
{
    if(z>max)
    {
        max=z;
    }
    //printf("%d %d %d %d$\n",x,y,max,s);
    for(int i=0; i<8; i++)
    {
        //printf("%d %d %d***\n",dx,dy,z);
        int dx=x+dir[i][0];
        int dy=y+dir[i][1];
        if(dx>=0&&dy>=0&&dx<m&&dy<n&&map[dx][dy]=='1')
        {
            //printf("%d %d %d %d*\n",dx,dy,z,s);
            map[dx][dy]='0';
            z++;
            dfs(dx,dy);
            //printf("%d %d %d %d**\n",dx,dy,z,s);
        }
    }
}
int main()
{
    scanf("%d%d%d",&m,&n,&t);
    max=0,s=0;
    int i,j;
    for( i=0; i<m; i++)
    {
        for( j=0; j<n; j++)
        {
            scanf(" %c",&map[i][j]);
            if(map[i][j]==' ')
            {
                j--;
            }
        }
    }
    /*printf("\n");
    for( i=0; i<m; i++)
    {
        for( j=0; j<n; j++)
        {
            printf("%c",map[i][j]);
        }
        printf("\n");
    }*/
    for( i=0; i<m; i++)
    {
        for( j=0; j<n; j++)
        {
            if(map[i][j]=='1')
            {
                z=0;
                //printf("%d %d\n",i,j);
                s++;
                map[i][j]='0';
                dfs(i,j);
            }
        }
    }
    printf("%d %d\n",s,(max+1)*t);
}




总结 ;
注意小方面的东西
这俩错误我找了一晚上  
不过收获也不小  提高了dbug的能力








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值