其他分享
首页 > 其他分享> > No 4.5 宝岛探险

No 4.5 宝岛探险

作者:互联网

简单介绍:在一个二维格子上面的一点,其相邻的格子:0表示海洋,1~9表示陆地,求一个目标格子所在的岛面积。

注意:与目标点上下左右相链接的陆地视为同一岛屿,不纠结其他四个角!

一、广度优先 VS 深度优先

/* No.1 广度优先搜索
#include <stdio.h>
struct node{  //广度优先,一定有一个队列用来存储父子节点
  int x;
  int y;
};
int book[50][50]={0};

int main(){
  struct node que[100];
  int head=1,tail=1;

  int m[50][50];
  int i,j,k,sum=0;
  int n,m,p,q,tx,ty;

  int next[4][2]={
    {0,1},{1,0},{0,-1},{-1,0} //{1,1},{1,-1},{-1,-1},{-1,1}
  };

  scanf("%d %d %d %d",&n,&m,&p,&q);  //犯了个错,scanf里面加了",",输入的时候没加!
  for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
      scanf("%d",&m[i][j]);      //与 char m[i][j]区别

  if(m[p][q]!=0)
  {
    que[tail].x=p;
    que[tail].y=q;
    sum++;
    book[p][q]=1;
    tail++;
  }

  while(head<tail){
    for(k=0;k<3;k++){
      tx=que[head].x+next[k][0];
      ty=que[head].y+next[k][1];
      if(tx<1||tx>10||ty<1||ty>10)
        continue;
      if(m[tx][ty]!=0 && book[tx][ty]==0){
        sum++;
        book[tx][ty]=1;
        que[tail].x=tx;
        que[tail].y=ty;
        tail++;
      }
    }
    head++;  //一定要记住,父节点的出栈
  }
  printf("%d",sum);
  getchar();getchar();
  return 0;
}
*/

/* No.4 深度优先搜索
#include <stdio.h>
int book[50][50];  //边界大点,否则结果可能不准确
int n,m,p,q,sum;
int map[50][50];
void dfs(int x,int y){
  int k,tx,ty;
  int next[4][2]={
    {0,1},{1,0},{0,-1},{-1,0} //{1,1},{1,-1},{-1,-1},{-1,1}
  };
  for(k=0;k<=3;k++){
    tx=x+next[k][0];
    ty=y+next[k][1];
    if(tx<0 ||tx>n || ty<0 ||ty>m)
      continue;
    if(map[tx][ty]!=0 && book[tx][ty]==0){
      sum++;
      book[tx][ty]=1;
      dfs(tx,ty);
    }
  }
  return ;  //千万不要忘了这一句,返回上一层dfs
}

int main(){
  int i,j;
  scanf("%d %d %d %d",&n,&m,&p,&q);
  for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
      scanf("%d",&map[i][j]);
  if(map[p,q]!=0){
    sum++;
    book[p][q]=1;
    dfs(p,q);
  }
  printf("%d",sum);
  getchar();getchar();
  return 0;
}
*/

 

二、更进一步:要求将上述岛标记出来

int book[50][50];
int n,m,p,q;
int map[50][50];
void dfs(int x,int y,int color){
  int k,tx,ty;
  int next[4][2]={
    {0,1},{1,0},{0,-1},{-1,0} //{1,1},{1,-1},{-1,-1},{-1,1}
  };
  map[x][y]=color;  //添加一个颜色标记就好了
  for(k=0;k<=3;k++){
    tx=x+next[k][0];
    ty=y+next[k][1];
    if(tx<0 ||tx>n || ty<0 ||ty>m)
      continue;
    if(map[tx][ty]!=0 && book[tx][ty]==0){
      book[tx][ty]=1;
      dfs(tx,ty,color);
    }
  }
  return ;
}

int main(){
  int i,j;
  scanf("%d %d %d %d",&n,&m,&p,&q);
  for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
      scanf("%d",&map[i][j]);
  if(map[p,q]!=0){
    book[p][q]=1;
    dfs(p,q,-1);
  }

  for(i=1;i<=n;i++)  //下面的两个 {} 不能省略
  {  

    for(j=1;j<=m;j++)
      {printf("%3d",map[i][j]);}
    printf("\n");
  }
  getchar();getchar();
  return 0;
}

 

三、再进一步:把图中独立的小岛,分别标记出来

#include <stdio.h>
int book[50][50]={0};
int n,m,p,q;
int map[50][50];
void dfs(int x,int y,int color){
  int k,tx,ty;
  int next[4][2]={
    {0,1},{1,0},{0,-1},{-1,0} //{1,1},{1,-1},{-1,-1},{-1,1}
  };

  map[x][y]=color;
  for(k=0;k<=3;k++){
    tx=x+next[k][0];
    ty=y+next[k][1];
    if(tx<0 ||tx>n || ty<0 ||ty>m)
      continue;
    if(map[tx][ty]!=0 && book[tx][ty]==0){
      book[tx][ty]=1;
      dfs(tx,ty,color);
    }
  }
  return ;
}

int main(){
  int i,j,color=0;
  scanf("%d %d",&n,&m);
  for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
      scanf("%d",&map[i][j]);

  for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
    {
      if(map[i][j]>0)  // 这里居然不能继续添加 && book[i][j]=0 条件
      {
        color--;
        book[i][j]=1;
        dfs(i,j,color);
      }
    }

  for(i=1;i<=n;i++)
  {

     for(j=1;j<=m;j++)
      {printf("%3d",map[i][j]);}
    printf("\n");
  }
  printf("共有%d个小岛",-color);
  getchar();getchar();
  return 0;
}

标签:4.5,map,tx,ty,int,No,50,宝岛,book
来源: https://www.cnblogs.com/yalimy/p/15041072.html