问题描述
所有SZSZ 学生翘首以盼的新教学楼总算快要竣工了,接下来到了网络布线的时候。网络系统的总布局是由nn台计算机组成的有线局域网,每根网线长度为dd,正常情况下,网线是可以缠绕使其变短但是不能拉长的,即每台计算机都能跟与它距离不超过dd的任何计算机通讯。
OIerOIer们试着一台一台地调试计算机网络,以构建整个局域网。有时在构建的过程中,他们需要测试一下某两台计算机能否通讯(如果他们能通过别的正常的计算机进行通 讯,也算他们之间可以通讯,即“能否通讯”可以是间接的)。作为OIerOIer,你自然也逃不掉模拟修复网络过程的任务,同时你还要回答“能否通讯”的询问。
输入格式
第一行两个整数,nn和dd,nn 表示计算机的数目,dd 表示网线的长度。接下来的nn行,每行两个整数Xi,YiXi,Yi,表示每台计算机的坐标。
接下来有许多行,每行都是一个操作(或者是修复操作,或者是询问操作)。
操作的格式如下:
O pO p 修复操作,表示修复编号为pp 的电脑;
S p qS p q 询问操作,询问编号为pp 和编号为qq 的电脑能否通讯。
以上操作,均保证1≤p≤n,1≤q≤n1≤p≤n,1≤q≤n
如果一台电脑尚未被修复,则它不能和任何电脑通讯。
输出格式
对于每个询问操作:如果能够通讯,输出一行SUCCESSSUCCESS;如果无法通讯, 输出一行FAILFAIL。
输入样例
3 1
0 1
0 2
0 3
O 1
O 3
S 1 3
O 2
S 1 3
输出样例
FAIL
SUCCESS
数据规模
设操作次数为qq
对于50%的数据,n≤300n≤300, q≤10000q≤10000;
对于100%的数据,n≤1001n≤1001, q≤300000q≤300000, 1≤d≤200001≤d≤20000, 0≤|xi|≤109,0≤|yi|≤1090≤|xi|≤109,0≤|yi|≤109。
题目分析
这一题给我留下了深深的阴影,倒也不是很难,就是很坑。我们要查找的是每两个点是否相等,如果你用旋转卡柯我没有办法,我的做法是用一个数组记录入图的点,然后把这些点用并查集维护即可。输出的时候判断一下两个点是否都已经被访问过了,三目输出即可。
坑点来了:我交了几发,发现自己爆零了,最后我发现:我在递归函数加了一个inline,然后我就死的很壮烈。记住:递归函数不要用这货。
代码实现
#include<bits/stdc++.h> using namespace std; #define RE register long long #define int long long #define N 1001 inline int read(){ register int x=0; register char c=getchar(); while(c<48) c=getchar(); while(c>47) x=x*10+(c^48),c=getchar(); return x; }int x[N],y[N],f[N],n,d,p,q,top,a[N]; int vis[N]; int find(RE x){return f[x]==x?x:f[x]=find(f[x]);} signed main(){ freopen("net.in","r",stdin),freopen("net.out","w",stdout); n=read(),d=read(); for (RE i=1;i<=n;++i) x[i]=read(),y[i]=read(),f[i]=i; char c; while(~scanf("%c",&c)){p=read(); if(c=='O'){ for (RE i=1;i<=top;++i){q=a[i]; if ((x[p]-x[q])*(x[p]-x[q])+(y[p]-y[q])*(y[p]-y[q])<=d*d) if (find(p)^find(q)) f[find(p)]=find(q); }a[++top]=p,vis[p]=1; }else{q=read(); if (!vis[p]||!vis[q]) puts("FAIL"); else puts(find(p)==find(q)?"SUCCESS":"FAIL"); } }return 0; }
代码分析
我的代码很容易看懂,不分析了。
哦,我还要讲我被绿的故事:1,开篇点题,引出本文“绿”的主旨。2,设置悬念,吸引读者阅读兴趣。3,采用了夸张的修辞手法,夸张了事情的严重性,使读者易于接受。
呃,其实没有啦,我们好着呢。
浙公网安备 33010602011771号