[USACO08OPEN]牛的街区Cow Neighborhoods
Posted liguanlin1124
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[USACO08OPEN]牛的街区Cow Neighborhoods相关的知识,希望对你有一定的参考价值。
题目描述:
题解:
技巧题。
曼哈顿距离:$|x1-x2|+|y1-y2|$
切比雪夫距离:$\max(|x1-x2|,|y1-y2|)$
曼哈顿距离转切比雪夫距离:$(x,y)->(x+y,x-y)$
所以……排完序拿stl::set模拟就好了。
代码:
#include<set> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int N = 100050; template<typename T> inline void read(T&x) T f = 1,c = 0;char ch=getchar(); while(ch<‘0‘||ch>‘9‘)if(ch==‘-‘)f=-1;ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘)c=c*10+ch-‘0‘;ch=getchar(); x = f*c; int n,c,ff[N],siz[N]; int findff(int x)return x==ff[x]?x:ff[x]=findff(ff[x]); void merge(int x,int y) x = findff(x),y = findff(y); if(x!=y)ff[x] = y,siz[y]+=siz[x]; struct Point ll x,y;int id; Point() Point(ll x,ll y):x(x),y(y) bool operator < (const Point&a)constreturn x!=a.x?x<a.x:y<a.y; p[N]; bool cmp(Point a,Point b)return a.y!=b.y?a.y<b.y:a.x<b.x; set<Point>tr; int main() read(n),read(c);ll x,y; for(int i=1;i<=n;i++) read(x),read(y); p[i] = Point(x+y,x-y); sort(p+1,p+1+n,cmp); for(int i=1;i<=n;i++) siz[i]=1,ff[i]=i,p[i].id=i; set<Point>::iterator it;Point now; for(int i=1,j=1;i<=n;i++) while(p[i].y-p[j].y>c)tr.erase(p[j]),j++; it = tr.lower_bound(p[i]); if(it!=tr.end()) now=(*it); if(now.x-p[i].x<=c)merge(now.id,i); if(it!=tr.begin()) it--;now=(*it); if(p[i].x-now.x<=c)merge(now.id,i); tr.insert(p[i]); int ans1 = 0,ans2 = -1; for(int i=1;i<=n;i++) if(findff(i)==i)ans1++,ans2=max(ans2,siz[i]); printf("%d %d\n",ans1,ans2); return 0;
以上是关于[USACO08OPEN]牛的街区Cow Neighborhoods的主要内容,如果未能解决你的问题,请参考以下文章
洛谷 P2909 [USACO08OPEN]牛的车Cow Cars
P2953 [USACO09OPEN]牛的数字游戏Cow Digit Game
P2953 [USACO09OPEN]牛的数字游戏Cow Digit Game