博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
「洛谷P2906」[USACO08OPEN]牛的街区Cow Neighborhoods 解题报告
阅读量:5892 次
发布时间:2019-06-19

本文共 5521 字,大约阅读时间需要 18 分钟。

题目描述

Those Who Know About Cows are aware of the way cows group into 'Cow Neighborhoods'. They have observed Farmer John's N (1 <= N <= 100,000) cows (conveniently numbered 1..N) as they graze, each at her own unique integer rectilinear coordinate, on a pasture whose X and Y coordinates are in the range 1..1,000,000,000.

Two cows are neighbors if at least one of two criteria is met:

1) If the cows are no further than some integer Manhattan distance C (1 <= C <= 1,000,000,000) apart, they are neighbors. [Manhattan distance is calculated as d = |x1-x2| + |y1-y2|.] 2) If cow A is a neighbor of cow Z and cow B is a neighbor of cow Z, then cow A is a neighbor of cow B (the 'transitive closure of neighbors').

Given the locations of the cows and the distance C, determine the the number of neighborhoods and the number of cows in the largest neighborhood.

By way of example, consider the pasture below. When C = 4, this pasture has four neighborhoods: a big one on the left, two neighborhoods of size 1 (the lonesome cows), and a huge neighborhood on the right with 60 different cows.

.....................................*................. ....*...*..*.......................***................. ......*...........................****................. ..*....*..*.......................*...*.******.*.*..... ........................*.............***...***...*.... *..*..*...*..........................*..*...*..*...*... .....................................*..*...*..*....... .....................................*..*...*..*....... ...*................*.................................. .*..*............................*.*.*.*.*.*.*.*.*.*.*. .*.....*..........................*.*.*.*.*.*.*.*.*.*.* ....*..................................................

The input file describes cow locations by integer X,Y coordinates, where the lower left corner is (1,1) and cows close to that corner appear at both (2,2) and (5,1) in the example above.

For a given pasture, determine both the number of cow neighborhoods and the number of cows resident in the largest cow neighborhood.

The above picture is sample test case 2, which will be evaluated for you upon submission.

Partial feedback for some test cases will be provided on the first 10 submissions.

Time Limit: 2 seconds

Memory Limit: 32MB

了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的时候有一个独一无二的位置坐标\(X_i\),\(Y_i\)(\(1\leq X_i,Y_i\leq [1 \cdots 10^9]\)\(X_i,Y_i \in \text{整数}\).当满足下列两个条件之一,两只奶牛i和j是属于同一个群的:

  1. 两只奶牛的曼哈顿距离不超过\(C(1\leq C\leq 10^9)\),即\(|X_i - x_i|+|Y_i - y_i|\leq C\).

  2. 两只奶牛有共同的邻居.即,存在一只奶牛\(k\),使\(i\)\(k\)\(j\)\(k\)均同属一个群.

给出奶牛们的位置,请计算草原上有多少个牛群,以及最大的牛群里有多少奶牛

输入输出格式

输入格式:

* Line 1: Two space-separated integers: N and C

* Lines 2..N+1: Line i+1 describes cow i's location with two

space-separated integers: \(X_i\) and \(Y_i\)

输出格式:

* Line 1: A single line with a two space-separated integers: the number of cow neighborhoods and the size of the largest cow neighborhood.

输入输出样例

输入样例#1:

4 2 1 1 3 3 2 2 10 10

输出样例#1:

2 3

说明

There are 2 neighborhoods, one formed by the first three cows and the other being the last cow. The largest neighborhood therefore has size 3.


思路

有思考深度的好题呀!(注意下\(X_i\)\(x_i\)表示的意义是不同的

我们观察两个点\(i\)\(j\)的曼哈顿距离\(|X_i-X_j|+|Y_i-Y_j|\)

  • 如果\(X_i-X_j\)\(Y_i-Y_j\)同号,曼哈顿距离为\(|X_i+Y_i-(X_j+Y_j)|\),且\(|X_i-Y_i-(X_j-Y_j)|\)偏小

  • 如果异号,曼哈顿距离为\(|X_i-Y_i-(X_j-Y_j)|\),且\(|X_i+Y_i-(X_j+Y_j)|\)偏小

因此,我们发现,如果设\(x_i=X_i+Y_i\)\(y_i=X_i-Y_i\)\(i\)\(j\)之间的曼哈顿距离即为\(\max(|x_i-x_j|,|y_i-y_j|)\)

然后用平衡树multiset一通乱搞就可以啦!

我们按照\(x_i\)为第一关键字,\(y_i\)为第二关键字排序,依次处理每个点。设当前处理的点为\(i\)。我们用并查集维护一个个群。

首先把所有\(x\)值小于\(x_i-C\)的点全部\(erase\)(删除)掉。

寻找第一个大于等于\(y_i\)的点\(j\)(lower_bound)。如果\(y_j-y_i\le C\),很明显,\(j\)\(i\)是同一个群的。

但是如果还有大于\(y_i\)的点\(k\)也满足条件呢?很明显,如果\(y_k-y_i\le C\),那么\(y_k-y_j\le y_k-y_i\le C\),在处理\(j\)\(k\)的时候已经将它们合并(这取决于\(x\)的大小),不必再管。

然后再康康小于\(y_i\)的点有没有符合条件的就好啦!

代码

#include
using namespace std;#define IT multiset
::iterator#define MAXN 100005#define LL long long#define pi pair
struct node{ int x, y; bool operator < ( const node &t )const{//重载运算符 if ( x == t.x ) return y < t.y; return x < t.x; } void input(){ scanf( "%d%d", &x, &y ); x = x + y, y = x - y - y;//读入并把X、Y转换成x、y }}a[MAXN];multiset
s;//因为要合并,还得记录编号(排序后的)。。所以用了个pairIT p[MAXN];//迭代器数组,用于删除x过小的元素int f[MAXN], sm[MAXN];//并查集、记录每个群的牛数(最后再处理int find( int x ){ return x == f[x] ? x : ( f[x] = find(f[x]) ); }void Merge( int x, int y ){ x = find(x); y = find(y); f[x] = y;}int N, C, x, y;int main(){ scanf( "%d%d", &N, &C ); for ( int i = 1; i <= N; ++i ) a[i].input(), f[i] = i; sort( a + 1, a + N + 1 ); s.insert( make_pair( 1ll << 60, -1 ) ); s.insert( make_pair( -( 1ll << 60 ), -1 ) );//避免边界问题 p[1] = s.insert(make_pair( a[1].y, 1 )); int tmp(1);//第一个点直接插入即可。 for ( int i = 2; i <= N; ++i ){ while( a[i].x - a[tmp].x > C ) s.erase(p[tmp++]);//把不满足要求的点删除 IT t(s.lower_bound(make_pair( a[i].y, -1 )));//找第一个大于等于y的 if ( t->first - a[i].y <= C ) Merge( i, t->second );//满足要求,合并 t--;//找第一个小于y的 if ( a[i].y - t->first <= C ) Merge( i, t->second );//满足要求,合并 p[i] = s.insert( make_pair( a[i].y, i ) );//插入点并记录迭代器 } int ans1(0), ans2(0); for ( int i = 1; i <= N; ++i ){ if ( find(i) == i ) ans1++; ans2 = max( ans2, ++sm[find(i)] ); } printf( "%d %d\n", ans1, ans2 ); return 0;}

转载于:https://www.cnblogs.com/louhancheng/p/10293006.html

你可能感兴趣的文章
springboot(三)——application.properties和application.yml是何时解析的
查看>>
iOS 一个比较完美的 Growing TextView
查看>>
dubbo+zookeeper+springmvc+mybatis分布式大型互联网企业架构
查看>>
关于 异步 的一些思考
查看>>
密码学基础(二)算法和密钥
查看>>
Android内存泄漏场景
查看>>
你觉得程序员最大的悲哀是什么?
查看>>
公众号是怎么赚钱的
查看>>
前端开发学习Day16
查看>>
云服务器都是有哪些特点? 云服务器有更高的性价比
查看>>
Effective Objective-C 2.0 第一章学习
查看>>
微服务分布式企业框架 Springmvc+mybatis+shiro+Dubbo+ZooKeeper+Redis+KafKa
查看>>
技术专栏丨从原理到应用,Elasticsearch详解(下)
查看>>
Python数据分析入门(三)
查看>>
JavaScript面向对象详解(原理)
查看>>
一个用Git交互可视化教学的项目
查看>>
LSM存储引擎基本原理
查看>>
webstrom编辑器scss环境以及ES6环境配置
查看>>
使用 Hbuild 快速构建生成现代化前端项目
查看>>
Windows虚拟环境在PyCharm中的使用
查看>>