洛谷恐怖的社会老师题解

恐怖的社会老师

题面:MX是一个7年级的学生,这天老师手持一把屠龙宝刀和一张等高线地形图,把刀插在MX的桌子上,逼迫MX告诉他 这张地图上有多少高原,平原,盆地,山地。 请你设置一个程序,救救MX。
输入方式:地图的长、宽 一个二维数组,上面有一些数值,表示高度,数字越大越高,山地和高原的高度在4及以上,完全高于四周(只包括东西南北)的是山地,多块同等是高原,盆地无高度限制,只要一块或多块的东西南北被包围就算是盆地,平原一定小于4且不是盆地即可 (地图之外全为0)(地图以内没有0)(地图之外全为0)(地图以内没有0)
输出方式:高原、平原、山地、盆地对应个数
input:

5
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
8 8 1 8 8
8 9 8 1 8

output:

2
2
1
0

这道题目有点恐怖啊。。

但这题的思维难度不大,就是2个dfs和循环罢了,注意盆地是不用dfs的!!

算了,先上代码吧:

/***********************
创作人:朱宏轩
时间:2020-03-03-16:00
***********************/

#include<bits/stdc++.h>  //神奇万能头
using namespace std;
int pinyuan=0;  //英语不好,就用一下拼音
int gaoyuan=0; 
int shandi=0;
int pendi=0;
int n;
int f[11][11];
bool gao[11][11]={};  //准备好暴力
bool pin[11][11]={};
bool sousuo[11][11]={};
bool shan(int i,int j){return f[i][j]>f[i-1][j]&&f[i][j]>f[i+1][j]&&f[i][j]>f[i][j-1]&&f[i][j]>f[i][j+1];}//一大堆判断函数
bool pen(int i,int j){return f[i][j]<f[i-1][j]&&f[i][j]<f[i+1][j]&&f[i][j]<f[i][j-1]&&f[i][j]<f[i][j+1];}
void gy(int i,int j,int sum){  //其实可以高原、平原一起判的~~(5555...)~~
	gao[i][j]=true;//标记这里走过了
	bool flag=false;//为下面铺垫
	if(f[i+1][j]==f[i][j]&&!gao[i+1][j]){
		gy(i+1,j,sum+1);flag=true;//只要往了一个方向走。就可以继续
	}
	if(f[i-1][j]==f[i][j]&&!gao[i-1][j]){
		gy(i-1,j,sum+1);flag=true;
	}
	if(f[i][j+1]==f[i][j]&&!gao[i][j+1]){
		gy(i,j+1,sum+1);flag=true;
	}
	if(f[i][j-1]==f[i][j]&&!gao[i][j-1]){
		gy(i,j-1,sum+1);flag=true;
	}
	if(!flag)//不能继续了
	if(sum>1)//sum==1时是山地,可惜我在主程序中就搞好了
	gaoyuan++;
}
void py(int i,int j){//基本和高原一样
	bool flag=false;
	pin[i][j]=true;
	if(f[i+1][j]==f[i][j]&&!pin[i+1][j]){
		py(i+1,j);flag=true;
	}
	if(f[i-1][j]==f[i][j]&&!pin[i-1][j]){
		py(i-1,j);flag=true;
	}
	if(f[i][j+1]==f[i][j]&&!pin[i][j+1]){
		py(i,j+1);flag=true;
	}
	if(f[i][j-1]==f[i][j]&&!pin[i][j-1]){
		py(i,j-1);flag=true;
	}
	if(!flag)pinyuan++;
}
int main()
{
    ios::sync_with_stdio(false);
    //cin和cout加速开关,加速后可能比scanf和printf还快~~(网络上有些说scanf和printf更快一点...)~~ 
	cin>>n;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	cin>>f[i][j];
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	{
		if(shan(i,j)){
			shandi++;
			sousuo[i][j]=true;//标记在一定程度上减小时间复杂度
		}
		if(pen(i,j)){
			pendi++;
			sousuo[i][j]=true;//标记在一定程度上减小时间复杂度
		}
	}
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	{
		if(!sousuo[i][j]){
			if(f[i][j]<4&&!pin[i][j])py(i,j);//如果没有被占用, 且可能为平原,就干他。
			if(f[i][j]>=4&&!gao[i][j])gy(i,j,1);//如果没有被占用, 且可能为高原,就干他。
		}
	}
	cout<<pinyuan<<endl;                                   
	cout<<gaoyuan<<endl;                                   
	cout<<shandi<<endl;                             
	cout<<pendi<<endl;   
	return 0; 
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值