蓝桥试题 历届真题 全球变暖(DFS-两种写法)

问题描述

  你有一张某海域NxN像素的照片,"."表示海洋、"#"表示陆地,如下所示:

  .......
  .##....
  .##....
  ....##.
  ..####.
  ...###.
  .......

  其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。

  由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。

  例如上图中的海域未来会变成如下样子:

  .......
  .......
  .......
  .......
  ....#..
  .......
  .......

  请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。

输入格式

  第一行包含一个整数N。 (1 <= N <= 1000)
  以下N行N列代表一张海域照片。

  照片保证第1行、第1列、第N行、第N列的像素都是海洋。

输出格式

  一个整数表示答案。

样例输入

7
.......
.##....
.##....
....##.
..####.
...###.
.......

样例输出

1

AC

#include<stdio.h>
#include<string.h>
#include<iostream>
char a[1100][1100];
int flag,n;
int vis[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
using namespace std;
void dfs(int x,int y)
{
	if(x<0||y<0)
		return ;//回溯
	if(x-1>=0&&a[x-1][y]!='.' && x+1<n&&a[x+1][y]!='.' && y-1>=0&&a[x][y-1]!='.' && y+1<n&&a[x][y+1]!='.')
	{
		flag=1;
	}
	if(a[x][y]=='#')
	{
		a[x][y]='*';
		for(int k=0;k<4;k++)
		{ 
			dfs(x+vis[k][0],y+vis[k][1]);
		}
	 }
	 return ; 
	

	 
	 return ; 
}


int main(void)
{
	int ans;
	ans=0;
	cin>>n;
	getchar();
	for(int i=0;i<=n;i++)
	{
		scanf("%s",a[i]);
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(a[i][j]=='#')
			{
				flag=0;
				dfs(i,j);
				if(flag==0)
				{
					ans++;
				}
				//flag=0;	
			}
		} 
	}
	cout<<ans<<endl;
	return 0;
 } 

AC

#include<stdio.h>
#include<string.h>
#include<iostream>
char a[1100][1100];
int flag,n;
int vis[4][2]= {{0,1},{1,0},{0,-1},{-1,0}};
using namespace std;
void dfs(int x,int y)
{
// 	if(flag) return;
	
// 	cout<<"^ "<<x<<" "<<y<<"\n";

	if(x-1>=0&&a[x-1][y]!='.' && x+1<n&&a[x+1][y]!='.' && y-1>=0&&a[x][y-1]!='.' && y+1<n&&a[x][y+1]!='.')
	{
		flag=1;
// 		cout<<"yes\n\n";
	}
		


// 	if(flag) return;

	for(int i=0; i<4; i++)
	{
		int nx=vis[i][0]+x,ny=vis[i][1]+y;
		if(nx<0 || nx>=n || ny<0 || ny>=n) continue;
		if(a[nx][ny]=='.' || a[nx][ny]=='*') continue;

		a[nx][ny]='*';

		dfs(nx,ny);
	}

	return ;
}


int main(void)
{
	int ans;
	ans=0;
	cin>>n;
	getchar();
	for(int i=0; i<n; i++)
		scanf("%s",a[i]);

//	for(int i=0; i<n; i++)
//		cout<<a[i]<<"\n";

	for(int i=0; i<n; i++)
	{
		for(int j=0; j<n; j++)
		{
			if(a[i][j]=='#')
			{
				flag=0;
				a[i][j]='*';
				dfs(i,j);
				if(flag==0)
				{
					ans++;
				// 	cout<<"#"<<i<<" "<<j<<"\n"; 
				}
			}
		}
	}
	cout<<ans<<"\n";
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值