ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

NOI科目校 信息学知识点测评-图论专题【51nod】 游记

2021-11-30 21:02:02  阅读:330  来源: 互联网

标签:知识点 NOI .. 10 51nod 样例 int 1005 ..........


比赛地址:Link

A 颜色块

1.0 秒 131,072.0 KB 100 分
一张 \(m\times n\) 的图片,每个点有一个颜色,相同颜色的点连在一起(上下左右四连通)属于同一个颜色块,问这张图片共有多少个颜色块。数据保证单个颜色块的点数量不超过 \(10^5\)。

输入

第一行:2个数\(n\),\(m\),中间用空格分隔,表示地图的大小(\(1 <= m, n <= 1000\))。
后面\(n\)行:每行\(m\)个字符,对应图片中的点的颜色编号\(c\)。(\(0 <= c <= 9\))。

输出

输出一个数,对应颜色块的数量

数据范围

\(1 <= m, n <= 1000\)

输入样例

5 5
11122
33112
31113
22113
21111

输出样例

5

样例解释

整个图中,有1个颜色为1的色块,2个颜色为2的色块,2个颜色为3的色块,因此共有5个色块。

通过记录

唰唰唰!秒杀!
毫无任何问题。

代码

#include<bits/stdc++.h>
using namespace std;
int mp[1005][1005];//存地图
bool v[1005][1005];//visited
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//四个方向
int m,n,ans=0;//ans=颜色块个数
void dfs(int x,int y){
	v[x][y]=1;//设置为标记过
	for(int i=0;i<4;i++){
		int dx=dir[i][0]+x,dy=dir[i][1]+y;
		if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&!v[dx][dy]&&mp[dx][dy]==mp[x][y]) dfs(dx,dy);//符合条件
	}
}
int main(){
	char c;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>c;
			mp[i][j]=c-'0';//过于紧凑
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(!v[i][j]){//每个都找一遍
				dfs(i,j);
				ans++;
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}

B 冬奥会之积水问题

3.0 秒 131,072.0 KB 100 分
冬奥会赛场旁有一片正方形的洼地(长宽都为\(n\)),地形凹凸不平,洼地的四周是一圈排水池。有一天,下了很大的雨,洼地形成了积水,告诉你洼地的地形(\(n\times n\)块的高度),由你来计算,洼地的积水量。

例如:\(n = 4\)

3 4 5 6
4 1 2 7
5 1 2 8
6 7 8 9

因为四周都是排水池(边界上的水会通过排水池流走),最终只有橘色部分(内圈):

1 2
1 2

能够形成积水,积水高度由他们4周(绿色部分,外圈)的最低高度决定,这个高度是4(左上角0,0位置的3虽然小于4,但2个高度为4的方块已经形成了封闭的一圈),所以总的积水量是10。

输入

第一行:一个数n,表示洼地的大小(\(3 <= n <= 1000\))
后面n行:每行n个数,表示地形的高度h[i,j](\(0 <= h[i,j] <= 1000000\))。

输出

输出总的积水量。

输入样例

4
3 4 5 6
4 1 2 7
5 1 2 8
6 7 8 9

输出样例

10

思路

floodfill。
模拟海平面,每次增高都尝试流一遍。

悲惨de做题过程

最开始写了一发,惨拿46TAT
结果发现数组开小了/kx
然后卡在91卡了0.5h,终于发现写的时候没有处理0,顺序反了/kx
然后就100了/cy
这告诉了我们:一定要搞清楚you在干什么!!!!!

code

#include<bits/stdc++.h>
using namespace std;
#define int long long
int mp[1005][1005];//地图
char vis[1005][1005];//是的,其实没啥用
struct three{
	int gao,x,y;//gao是高度
	bool operator <(three b) const{
		return gao>b.gao;
	}
};
priority_queue<three> q;
int n,m,mx=-1;
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
signed main(){
	cin>>n;
	m=n;
	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){cin>>mp[i][j];mx=max(mx,mp[i][j]);}//mx存最大值
	for(int i=1;i<=m;i++){//处理四周
		q.push({mp[1][i],1,i});
		q.push({mp[n][i],n,i});
		vis[1][i]=2;
		vis[n][i]=2;
	}
	for(int i=1;i<=n;i++){
		q.push({mp[i][1],i,1});
		q.push({mp[i][m],i,m});
		vis[i][1]=2;
		vis[i][m]=2;
	}
	int ans=0,hpm=0;//hpm=海平面
	three now;
	while(!q.empty()&&hpm<=mx){
	//cout<<q.top().gao<<' '<<hpm<<endl;
		now=q.top();
		while(!q.empty()&&now.gao<=hpm){
			if(vis[now.x][now.y]==1){//这地方被淹了
				ans+=hpm-now.gao;
				//cout<<now.x<<","<<now.y<<":"<<now.gao<<" "<<hpm<<endl;
			}
			q.pop();
			vis[now.x][now.y]=2;
			for(int i=0;i<4;i++){
				int dx=now.x+dir[i][0];
				int dy=now.y+dir[i][1];
				if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&!vis[dx][dy]){//查看四周
					vis[dx][dy]=1;
					q.push({mp[dx][dy],dx,dy});
				}
			}
			now=q.top();
		}
		hpm++;
	}
	cout<<ans<<endl;
	return 0;
}
/*以下是自造测试数据
4
0 2 100 0
10000 1 1 233
114 1 1 514
0 123 456 0
10
0 0 0 0 1 1 1 0 0 0
0 0 1 1 0 0 0 1 0 0
0 1 0 0 0 0 0 0 1 0
1 0 0 0 0 0 0 0 1 0
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0 1 0
0 0 1 0 0 0 0 1 0 0
0 0 0 1 1 1 1 0 0 0
*/

(C没做出来不放了)

D 黏菌网络

1.0 秒 131,072.0 KB 100 分
小明正在研究黏菌(slime molds)。他有一张网状格栅,共\(10\times10\)个交点,每个交点上可以放置一些物体。他选择了其中3个交点,分别放置黏菌(M),糖(S),以及一块有毒物质(P),如下所示:

..........
..........
..........
..S.......
..........
.....P....
..........
..........
.....M....
..........

之后观察黏菌是否能避开毒物,并沿网格以最短路线找到糖。

小明希望你先帮忙算出黏菌到达糖之前至少要经过多少个空交点,以便他做实验记录。

输入

输入共10行,每行一个长度为10的字符串描述\(10\times10\)格栅中交点的情况。其中'.'表示空交点,'M'表示放置了黏菌,'S'表示放置了糖,'P'表示放置了毒物。保证输入数据中仅存在一组'M','S','P'。

输出

输出一个整数,表示黏菌经过的空交点的最小数量。

输入样例

..........
..........
..........
..S.......
..........
.....P....
..........
..........
.....M....
..........

输出样例

7

样例解释

..........
..........
..........
..S.......
..7.......
..6..P....
..5.......
..4.......
..321M....
..........

如上所示,黏菌需要经过至少7个空交点。

思路

这题放在T4也是绝了,是四道题里最简单的。
一个障碍,\(10\times 10\)大小,也不过如此。
直接爆搜。

通过记录

直接写。

code

#include<bits/stdc++.h>
using namespace std;
int n=10,sx,sy,ex,ey,ans=0;//startx,starty,endx,endy
bool mp[15][15];//map
bool v[15][15];//visited
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
struct th{//three
	int x,y,stp;
}now;
queue<th> q;
int bfs(){//bfs
	q.push({sx,sy,0});
	v[sx][sy]=1;
	while(!q.empty()){
		now=q.front();
		if(now.x==ex&&now.y==ey) return now.stp-1;//end
		q.pop();
		for(int i=0;i<4;i++){
			int dx=dir[i][0]+now.x,dy=dir[i][1]+now.y;
			if(dx>=1&&dx<=n&&dy>=1&&dy<=n&&!mp[dx][dy]&&!v[dx][dy]){//ok
				v[dx][dy]=1;
				q.push({dx,dy,now.stp+1});
			} 
		}
	}
	return -1;
}
int main(){
	char c;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++){
			cin>>c;
			if(c=='M') sx=i,sy=j;//m
			else if(c=='S') ex=i,ey=j;//s
			else if(c=='P') mp[i][j]=1;//p
		}
	cout<<bfs()<<endl;
	return 0;
}

标签:知识点,NOI,..,10,51nod,样例,int,1005,..........
来源: https://www.cnblogs.com/tigerchen/p/this_is_a_shui_wen.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有