【JZOJ】【BFS】WZK旅游

10 篇文章 0 订阅

D e s c r i p t i o n Description Description

在一个n*m的图中
有很多数
如果在某一部分的数字中(也有可能只有一个)
数值都一样
且比周围(不包括对角)的数字大
那么称之为山
如果小的话
就称之为湖
问这张图中有多少个山与湖

I n p u t Input Input

第一行,两个数,n,m
第2~n+1行,每行m个数,描述的是n*m的图

O u t p u t Output Output

两个数,湖与山的数量

S a m p l e I n p u t Sample Input SampleInput#1
2 2
1 2
1 1
S a m p l e I n p u t Sample Input SampleInput#2
3 4
1 3 2 6
1 2 2 7
3 2 2 5
S a m p l e O u t p u t Sample Output SampleOutput#1
1 1
S a m p l e O u t p u t Sample Output SampleOutput#2
1 3

思路

广搜
将连在一起且相同的数字记录下来
判断是否为周围中最小或最大的

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int dx[5]={0,0,0,1,-1};
const int dy[5]={0,1,-1,0,0};
int A[1250][1250],F[1250][1250];
int Ans_lake,Ans_mountain;
int Min,Max,n,m;
queue<int>x;
queue<int>y;
bool Check(int x,int y)
{
	if(x<1 || x>n || y<1 ||y>m)return 0;
	return 1;
}
void IGNB(int l,int r)
{
	x.push(l),y.push(r);
	F[l][r]=1;
	while(x.size())
	{
		int xx=x.front();x.pop();
		int yy=y.front();y.pop();
		for(int i=1;i<=4;++i)//四个方向
			if(Check(xx+dx[i],yy+dy[i]))//判断是否超界
			{
				if(A[xx+dx[i]][yy+dy[i]]==A[xx][yy])//判断是否同值
				{
					if(!F[xx+dx[i]][yy+dy[i]])//判断是否走过
					{
						F[xx+dx[i]][yy+dy[i]]=1;//记录为走过
						x.push(xx+dx[i]);
						y.push(yy+dy[i]);
					}
				}
				else
				{
					Min=min(Min,A[xx+dx[i]][yy+dy[i]]);//判断周围的最高和最低
					Max=max(Max,A[xx+dx[i]][yy+dy[i]]);
				}
			}
	}
}
int main()
{
	freopen("seek.in","r",stdin);
	freopen("seek.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
			scanf("%d",&A[i][j]);
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
			if(!F[i][j])//如果没到过
			{
				Min=1e9;
				Max=-1e9;
				IGNB(i,j);
				if(Min>A[i][j] && Min!=1e9)
					Ans_lake++;//判断是否为湖
				if(Max<A[i][j] && Max!=-1e9)
					Ans_mountain++;//判断是否为山
			}
	printf("%d %d",Ans_lake,Ans_mountain);
	fclose(stdin);
	fclose(stdout);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值