http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3521
ATTENTION: If you use long long to reduce the error, this problem can only be read in%LLD
The first thing you need to know is which points are next to each other, so it's easier than just maintaining which sets are frozen.
According to the X-based, y auxiliary sort, in the array on the ruler, when the head and tail x coordinate is greater than L/2, the head is moved backwards until the x-coordinate satisfies the condition,
So for head to tail, now the problem is only to detect which points between the Y-spacing is less than L/2, and they are joined in accordance with Pair<y,id> set, then the nearest two points from tail the y-coordinate is closest to the tail, if one of the points to meet the gap is less than L /2, then put the tail and this point in one and check the set, (other points if the conditions, will and these two points in a and check set)
Finally count which and check sets are frozen, and these and how many points in the concentration can be
#include <cstdio> #include <cstring> #include <set> #include <algorithm>using namespace std; typedef long LONG ll;typedef pair<ll,ll> p;const int maxn=5e4+3;int n;ll r,l; P pnt[maxn],o;int par[maxn];bool in[maxn];ll dis (p a,p b) {return (a.first-b.first) * (A.first-b.first) + ( A.second-b.second) * (A.second-b.second);} int fnd (int i) {return (par[i]==i?i: (PAR[I]=FND (Par[i)));} BOOL Same (int a,int b) {return fnd (a) ==fnd (b);} void Unite (int a,int b) {if (!same (b)) {Par[par[b]]=par[a]; }}void solve () {set<p> st; int head=0; for (int tail=0;tail<n;tail++) {while (2*abs (Pnt[tail].first-pnt[head].first) >l) { St.erase (P (Pnt[head].second,head)); head++; } Set<p>::iterator it = St.insert (P (Pnt[tail].second,tail)). First; if (It!=st.begin ()) {it--;//printf ("S:%lld%lld\n", It->first,pnt[tail].second); if (2*abs (Pnt[tail].second-it->first) <=l) {unite (Tail,it->second); } it++; } it++; if (It!=st.end ()) {if (2*abs (It->first-pnt[tail].second) <=l) {UN ITE (Tail,it->second); }}}}void output () {int ans=0; for (int i=0;i<n;i++) {if (DIS (pnt[i],o) <=r*r) {if (!IN[FND (i)]) { In[par[i]]=true; }}} for (int i=0;i<n;i++) {if (IN[FND (i)]) {ans++; }} printf ("%d\n", ans);} int main () {while (scanf ("%d%lld%lld", &n,&r,&l) ==3) {memset (in,0,sizeof (in)); for (int i=0;i<n;i++) { scanf ("%lld%lld",& (Pnt[i].first),& (Pnt[i].second)); Par[i]=i; } scanf ("%lld%lld",& (O.first),& (O.second)); Sort (pnt,pnt+n); Solve (); Output (); } return 0;}
ZOJ 3521 Fairy Wars OJ error title, calculate geometry, ruler method, sort binary tree, and find difficulty: 2