宝岛探险

宝岛探险

题目描述:
钓鱼岛是由一个主岛和一些附属岛屿组成,小哼决定去钓鱼岛探险。下面这个10*10的二维矩阵就是钓鱼岛的航拍地图。图中数字表示海拔,0表示海洋,1~9表示陆地。小哼的飞机将会降落在(6,8)处,现在需要计算出小哼降落地所在岛的面积(即有多少个格子)。

  输入
  第一行行数n,列数m,起始坐标
  第二行到第n+1行地图状态(0为海洋,其余为陆地)
  
  输出
  着地后陆地面积

  输入样例
    10 10 6 8
    1 2 1 0 0 0 0 0 2 3
    3 0 2 0 1 2 1 0 1 2
    4 0 1 0 1 2 3 2 0 1
    3 2 0 0 0 1 2 4 0 0
    0 0 0 0 0 0 1 5 3 0
    0 1 2 1 0 1 5 4 3 0
    0 1 2 3 1 3 6 2 1 0
    0 0 3 4 8 9 7 5 0 0
    0 0 0 3 7 8 6 0 1 2
    0 0 0 0 0 0 0 0 1 0

  输出样例
  38

这道题按常规的广搜解法即可,写这篇的目的并不是这题,而是介绍一种思想。着色法,以某个点为源点对其邻近的点进行着色。想这题的话,如果题目说求有多少个孤岛,即可用此法解决。

代码如下:

#include<iostream>
#include<cstdio>
using namespace std;
int n,m; //迷宫的行数列数 
int head ,tail ; //队列的头和尾 
int book[1001][1001]; //记录是否走过 
int map[1001][1001];   //记录地图 
int next[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
int sum = 1;
struct queue
{
   int x;
   int y;
};
queue Q[10001];//大小看情况而定 
void bfs(int x, int y)
{
   Q[1].x = x;
   Q[1].y = y;
   head = 1,tail = 2;
   while(head < tail)
   {
    for(int k = 0; k < 4; k ++)
    {
       int tx = Q[head].x + next[k][0]; 
    int ty = Q[head].y + next[k][1];
    if(tx < 1 || ty < 1 || tx > n || ty > m)
    continue;
    if(book[tx][ty] == 0 && map[tx][ty] > 0)
    {
     sum ++;
     book[tx][ty] = 1;
     Q[tail].x = tx;
     Q[tail].y = ty;
     tail ++;
    } 
 }
 head ++;
   }
   
}
int main()
{
   int startx,starty;
  
   scanf("%d%d",&n,&m);
   scanf("%d%d",&startx,&starty);
   for(int i = 1; i <= n; i ++)
   for(int j = 1; j <= m; j ++)
   scanf("%d",&map[i][j]);
 
   book[startx][starty] = 1;
   bfs(startx,starty); 
   cout << sum;
   return 0;
} 

上面说的着色法求孤岛数量,即可以用广搜对其中每个落点入队列,如果该队列中有该落点,则无需再入。
将该落点连接的陆地全部着色,即为-1,若发现其他落点有为染色,则着色为-2~~~~~直到所有入了队列

代码如下:

#include<iostream>
#include<cstdio>
using namespace std;
int n,m; //迷宫的行数列数 
int head ,tail ; //队列的头和尾 
int book[1001][1001]; //记录是否走过 
int map[1001][1001];   //记录地图 
int next[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
int sum = 1;
struct queue
{
   int x;
   int y;
};
queue Q[10001];//大小看情况而定 
void bfs(int x, int y,int color)
{
   map[x][y] = color;
   for(int k = 0; k < 4; k ++)
   {
    int tx = x + next[k][0];
    int ty = y + next[k][1];
    if(tx < 1 || ty < 1 || tx > n || ty >n)
    continue;
    if(map[tx][ty] > 0 && book[tx][ty] == 0)
    {
      book[tx][ty] = 1;
   bfs(tx,ty,color); 
 }
   }
}
int main()
{
   int startx,starty;
   int num = 0;
   scanf("%d%d",&n,&m);
   scanf("%d%d",&startx,&starty);
   for(int i = 1; i <= n; i ++)
   for(int j = 1; j <= m; j ++)
   scanf("%d",&map[i][j]);
 
   for(int i = 1; i <= n; i ++)
   for(int j = 1; j <= n; j ++)
   {
    if(map[i][j] > 0)
    {
     num --; 
     book[i][j] = 1;
     bfs(i,j,num);
 }
    
   }
   cout << -num;
   return 0;
} 

这是一种解题思想,若求独立节点,则可用这种思想。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值