原标题:技术图文:蓝桥杯 prev54 合根植物
背景
这段时间,LSGO软件技术团队的一个小组在准备明年3月份蓝桥杯的比赛。
我把他们写的算法题目转发过来,为其他准备蓝桥杯比赛的同学做个参考啊。
题目
问题描述
w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了了一株合根植物。这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?
输入格式
第一行,两个整数m,n,用空格分开,表示格子的行数、列数(1 < m, n < 1000)。接下来一行,一个整数k,表示下面还有k行数据(0 < k < 100000) 接下来 k 行,第行两个整数 a,b,表示编号为 a 的小格子和编号为 b 的小格子合根了。格子的编号一行一行,从上到下,从左到右编号。比如:5 * 4 的小格子,编号:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
样例输入
5 4 16 2 3 1 5 5 9 4 8 7 8 9 10 10 11 11 12 10 14 12 16 14 18 17 18 15 19 19 20 9 13 13 17
样例输出
5 样例说明 其合根情况参考下图
代码实现#include
#include
#include
usingnamespacestd;
vector< int> uset, weight;
intfind(intx){ // 返回x所在集合的终点或特征元
while(x != uset[x])
x = uset[x];
returnx;
}
intfind(intx){ // find 的递归写法
returnx == uset[x] ? x : find(uset[x]);
}
voiduni(intx, inty){ // 朴素写法
uset[find(x)] = find(y); // 将 x 集合的终点记作 y
}
voiduni(intx, inty){ // 赋权写法,每个子集只有一个特征元
intt1 = find(x), t2 = find(y);
if(weight[t1] > weight[t2])
uset[t2] = t1;
else{
uset[t1] = t2;
if(weight[t1] == weight[t2])
++weight[t2];
}
}
intmain{
intm, n, k, ans = 0;
scanf( "%d%d%d", &m, &n, &k);
for( inti = 0; i <= m * n; i++) { // init
uset.push_back(i);
weight.push_back( 0);
}
for( inti = 0; i < k; i++) {
intt1, t2;
scanf( "%d%d", &t1, &t2);
uni(t1, t2);
}
// 每个集合总存在这样一个终点,它的 find 值等于自身
for( inti = 1; i <= m*n; i++)
if(find(i) == i) // 一个并集的终点
ans++;
cout<< ans << endl;
return0;
}
参考文献
https://wushouyuan.com/posts/eae083a3/
LSGO软件技术团队会定期开展提升编程技能的刻意练习活动,希望大家能够参与进来一起刻意练习,一起学习进步!
经过8年多的发展,LSGO软件技术团队在「地理信息系统」、「数据统计分析」、「计算机视觉」等领域积累了丰富的研发经验,也建立了人才培养的完备体系,目前深耕的领域为「机器学习与量化金融」,欢迎对计算机技术感兴趣的同学加入,与我们共同成长进步。
后台回复「搜搜搜」,随机获取电子资源!返回搜狐,查看更多
责任编辑: