下面是题干:
问题描述
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
样例说明
其合根情况参考下图
前言:刚开始看这个题,我以为是深度搜索,因为刚学的深度搜索里面有一个类似的题目。然后仔细看了看发现这个题挺简单的,就是需要标记一下下标和前面的元素的关系。大概有了思路,但是实现起来很难。后来,看了别人的代码,才知道这里需要用到并查集,如果不知道这个知识的话可以提前去看一下。这里用到了它的合并,查找的操作。
另外,这个题看似是二维的但其实是一维的(因为有编号),我看有的人申请了一个数组int father[0x3f3f3f];
关于0x3f3f3f,我在末尾说明。
#include<cstdio>
#include<iostream>
#include<vector>//这里我不是用c中的数组的,而是用了向量
using namespace std;
vector <int> father;
int find_gen(int x)//找爸爸,在这里可以多添加一个路径压缩的代码,以防极端情况
{
int a = x;//记住你正在查询的那个节点
if (father[x] == x)
{
return x;
}
while (x != father[x])
{
x = father[x];
}
while (father[a] != a)//把a的上面的节点全都连接到根节点上面,以后查找就很快
{
int temp = father[a];
father[a] = x;
a = temp;
}
return x;
}
int unite(int x,int y)//合并集合
{
x=find_gen(x);
y=find_gen(y);
if(x!=y)
father[y] = x;
return 0;
}
int main(void)
{
int m, n,k;
int cnt = 0;
scanf_s("%d%d", &m, &n);
scanf_s("%d", &k);
int x, y;
int len = m * n;
for (int i = 0; i <=len; i++)
{
father.push_back(i);
}
for (int i = 0; i < k; i++)
{
cin >> x >> y;
unite(x, y);
}
for (int i = 1; i <= len; i++)
{
if (father[i] == i)
{
cnt++;
}
}
cout << cnt ;
return 0;
}
很多程序员都用0x7fffffff来作为无穷大的值,但是由于这个值过大,会出现无穷大加上一个有穷数,出现溢出的情况,由无穷大变成了一个负数。
而0x3f3f3f就是一个比较完美的无穷大的值的选择。
- 0x3f3f3f的十进制是1061109567,是10^9级别的,和0x7fffffff是一个数量级,而我们在写题是遇到的数据范围,一般都不会超过这个级别,因此可以作为无穷大。
- 另一方面,因为这个数并不算特别大,所以不会出现无穷大加上一个数据,出现溢出情形。甚至,0x3f3f3f3f+0x3f3f3f3f=2122219134,满足了无穷大加上无穷大还是无穷大的结果,与常识相符。
- 如果我们想要将某个数组清零,我们通常会使用memset(a,0,sizeof(a))这样的代码来实现,但是当我们想将某个数组全部赋值为其他值,例如无穷大时,就不能使用memset函数而得自己写循环了我们知道这是因为memset是按字节操作的,它能够对数组清零是因为0的每个字节都是0,现在好了,如果我们将无穷大设为0x3f3f3f3f,那么奇迹就发生了,0x3f3f3f3f的每个字节都是0x3f!所以要把一段内存全部置为无穷大,我们只需要memset(a,0x3f,sizeof(a))。