NBUT 1301-Gopher Hole【并查集+查询】 难度:**

题意:

Death-Moon loves telling stories.
Some days ago, he told us a funny story.

Long long ago, there is a hamster who is so naughty. Now, he comes to a place likes a N * N square. so, he is so excited to drill holes underground.

输入
Input until EOF.
Fisrt input two integers N (3 <= N < 100) and M (0 < M <2000). N is the side of N * N ground, M is the number of operations.

Then follow M lines.
Each line is a command:

Out x y : Hamster will get out at (x, y) from underground. So, place (x, y) will be a hole.
P : Calculate out the number of the holes and output (Two holes are connected when they share an edge).
If two holes are connected, it means it is one hole.
输出
For each ‘P’ command, output the number of the holes. Maybe hamster will get out at the same place more than once.
样例输入
3 5
Out 0 0
P
Out 1 0
Out 2 2
P
样例输出
1
2

题解:

题意可以概括为:相邻的洞可以连接为一个洞,挖洞的同时不断查询洞的个数。像这种n并1的题肯定是用并查集来解决。按照模板题的写法,每次查询个数需要整体遍历一遍,放在这道题一定会超时。因此我们可以维护一个sum值,每次加入新洞后,sum+=1-cot,其中cot表示加入这个洞后,该洞四周一共有几个独立的洞,查找几个独立的洞的方法就是分别比较四周洞的根结点是否相同(当然四周不一定都有洞),这样每次查询操作近似为O(1)。
(代码里的并查路径压缩函数写重了,不要介意哈)

代码:

#include<stdio.h>
int a[10005];
int findtop(int x)
{
	return x==a[x]?x:a[x]=findtop(a[x]);
}
int checktop(int x)
{
	return x==a[x]?x:checktop(a[x]);
}
int main()
{
	int n,m,x,y,t,sum,k1,k2,b[10];
	char ch[10];
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		for(int i=0;i<=(n+1)*(n+1);i++)a[i]=-1;
		sum=0;k1=0;
		while(m--)
		{
			scanf("%s",ch);
			if(ch[0]=='O')
			{
				scanf("%d%d",&x,&y);
				t=x*n+y;
				if(a[t]!=-1)continue;
				a[t]=t;
				k1=0;
				if(x!=n-1)if(a[t+n]!=-1){b[k1]=checktop(t+n);k1++;}
				if(x!=0)if(a[t-n]!=-1){b[k1]=checktop(t-n);k1++;}
				if(y!=n-1)if(a[t+1]!=-1){b[k1]=checktop(t+1);k1++;}
				if(y!=0)if(a[t-1]!=-1){b[k1]=checktop(t-1);k1++;}
				int temp=k1;
				for(int i=0;i<temp;i++)
				{
					for(int j=i+1;j<temp;j++)
					{
						if(b[i]==b[j]&&b[i]!=-1)
						{
							k1--;
							b[j]=-1;
						}
					}
				}
				if(x!=n-1)if(a[t+n]!=-1&&a[findtop(t)]!=a[findtop(t+n)])a[findtop(t)]=a[findtop(t+n)];
				if(x!=0)if(a[t-n]!=-1&&a[findtop(t)]!=a[findtop(t-n)])a[findtop(t)]=a[findtop(t-n)];
				if(y!=n-1)if(a[t+1]!=-1&&a[findtop(t)]!=a[findtop(t+1)])a[findtop(t)]=a[findtop(t+1)];
				if(y!=0)if(a[t-1]!=-1&&a[findtop(t)]!=a[findtop(t-1)])a[findtop(t)]=a[findtop(t-1)];
				sum=sum+1-k1;
			}
			else if(ch[0]=='P')printf("%d\n",sum);
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值