NBA每一年都有球员选秀环节。一般用速度和身高两项数据来衡量一个篮球运动员的基本素质。假如一支球队里速度最慢的球员速度为minV,身高最矮的球员高度为minH,那么这支球队的全部队员都应该知足: A * ( height
– minH ) + B * ( speed – minV ) <= C 其中A和B,C为给定的经验值。这个式子很容易理解,若是一个球队的球员速度和身高差距太大,会形成配合的不协调。 请问做为球队管理层的你,在N名选秀球员中,最多能有多少名符合条件的候选球员。c++
第一行四个数N、A、B、C 下接N行每行两个数描述一个球员的height和speed数组
最多候选球员数目。spa
4 1 2 10
5 1
3 2
2 3
2 1指针
4code
数据范围: N <= 5000 ,height和speed不大于10000。A、B、C在长整型之内。排序
这题也真是够神仙的队列
首先把式子变成这样ip
$Ax+By-C\le Aminx + Bminy $input
而后就从新取一个权值叫作\(val=Ax+By-C\)it
把原数组复制两遍,一个按照x排序,一个按照val排序
而后咱们先枚举miny,而后在内层枚举minx,可是同时怎么维护答案?
咱们用一个指针扫val加入答案,并用一个指针扫x删除答案
我第一次看到的时候心情就是wtf?
确实很神奇
如今咱们考虑加入答案的限制,首先y确定是要大于等于miny的,可是y应该有一个上界,否则\(y-miny\)太大致使在知足\(val\le Aminx+Bminy\)的条件下\(x< minx\)
既然不能让x超界,也就是要知足\(minx\le x\),那么就必定有
\(By\le Bminy + C\)
也就是说\(miny\le y\le miny + \frac{C}{B}\)
这样就能够同时扫按照x排序的队列来把x不知足的都删掉了(由于y对于全局的限制都是相等的)
???
好像推不过来吧,不过没事,在这道题里面是对的
如今来考虑另外一个事情:会不会有没有统计贡献的被删除贡献?
不可能的
被删除贡献的时候须要知足\(x<minx\)和\(min\le y\le miny+\frac{C}{B}\)
显然是知足\(Ax+By\le Aminx+Bminy+C\)的
那不就必定会在上面统计贡献吗?
因此就成立了。。。而后其实你也能够根据刚刚这个式子把\(By\le Bminy + C\)理解为让删除不重不漏的条件
#include<bits/stdc++.h> using namespace std; const int N = 5010; int n, A, B, C; int ans; struct Point { int x, y, val; Point() {} Point(int x, int y, int val): x(x), y(y), val(val) {} } p[N], q[N]; bool cmp1(const Point a, const Point b) { return a.x < b.x; } bool cmp2(const Point a, const Point b) { return a.val < b.val; } int main() { scanf("%d %d %d %d", &n, &A, &B, &C); for (int i = 1; i <= n; i++) { int x, y; scanf("%d %d", &x, &y); p[i] = q[i] = Point(x, y, A * x + B * y - C); } sort(p + 1, p + n + 1, cmp1); sort(q + 1, q + n + 1, cmp2); for (int i = 1; i <= n; i++) { int tp = 0, tq = 0, cur = 0; int dn = p[i].y, up = C / B + p[i].y; for (int j = 1; j <= n; j++) { int limit = A * p[j].x + B * p[i].y; while (tp < n && p[tp + 1].x < p[j].x) { ++tp; cur -= dn <= p[tp].y && p[tp].y <= up; } while (tq < n && q[tq + 1].val <= limit) { ++tq; cur += dn <= q[tq].y && q[tq].y <= up; } ans = max(ans, cur); } } printf("%d", ans); return 0; }