BZOJ 1071([SCOI2007]组队-双指针)
2017-01-31 04:45
489 查看
Description
NBA每年都有球员选秀环节。通常用速度和身高两项数据来衡量一个篮球运动员的基本素质。假如一支球队里
速度最慢的球员速度为minV,身高最矮的球员高度为minH,那么这支球队的所有队员都应该满足: A * ( height
– minH ) + B * ( speed – minV ) <= C 其中A和B,C为给定的经验值。这个式子很容易理解,如果一个球队的
球员速度和身高差距太大,会造成配合的不协调。 请问作为球队管理层的你,在N名选秀球员中,最多能有多少名
符合条件的候选球员。
Input
第一行四个数N、A、B、C 下接N行每行两个数描述一个球员的height和speed
Output
最多候选球员数目。
Sample Input
4 1 2 10
5 1
3 2
2 3
2 1
Sample Output
4
HINT
数据范围: N <= 5000 ,height和speed不大于10000。A、B、C在长整型以内。
将题意化简为平面上有一堆点,你需要放某个直角三角形(保证直角边平行坐标轴不能旋转斜边方向为\),问最多能框住几个点。
O(n^2)暴力双指针,这里注意斜边顺序入队,丨边顺序出队。
NBA每年都有球员选秀环节。通常用速度和身高两项数据来衡量一个篮球运动员的基本素质。假如一支球队里
速度最慢的球员速度为minV,身高最矮的球员高度为minH,那么这支球队的所有队员都应该满足: A * ( height
– minH ) + B * ( speed – minV ) <= C 其中A和B,C为给定的经验值。这个式子很容易理解,如果一个球队的
球员速度和身高差距太大,会造成配合的不协调。 请问作为球队管理层的你,在N名选秀球员中,最多能有多少名
符合条件的候选球员。
Input
第一行四个数N、A、B、C 下接N行每行两个数描述一个球员的height和speed
Output
最多候选球员数目。
Sample Input
4 1 2 10
5 1
3 2
2 3
2 1
Sample Output
4
HINT
数据范围: N <= 5000 ,height和speed不大于10000。A、B、C在长整型以内。
将题意化简为平面上有一堆点,你需要放某个直角三角形(保证直角边平行坐标轴不能旋转斜边方向为\),问最多能框住几个点。
O(n^2)暴力双指针,这里注意斜边顺序入队,丨边顺序出队。
#include<bits/stdc++.h> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,0x3f,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define MEMx(a,b) memset(a,b,sizeof(a)); #define INF (0x3f3f3f3f) #define F (1000000007) #define pb push_back #define mp make_pair #define fi first #define se second #define vi vector<int> #define pi pair<int,int> #define SI(a) ((a).size()) #define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans); #define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a <<endl; #define PRi2D(a,n,m) For(i,n) { \ For(j,m-1) cout<<a[i][j]<<' ';\ cout<<a[i][m]<<endl; \ } #pragma comment(linker, "/STACK:102400000,102400000") #define ALL(x) (x).begin(),(x).end() typedef long long ll; typedef long double ld; typedef unsigned long long ull; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return ((a-b)%F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f; } int n; ll A,B,C; struct pa{ ll x,y,s; }x[20000],y[20000]; inline bool cmp(pa a,pa b){ return a.x<b.x; } inline bool cmp2(pa a,pa b){ return a.s<b.s; } int main() { // freopen("bzoj1071.in","r",stdin); // freopen(".out","w",stdout); cin>>n>>A>>B>>C; For(i,n) cin>>x[i].x>>x[i].y ,x[i].s=x[i].x*A+x[i].y*B,y[i]=x[i]; sort(x+1,x+1+n,cmp); sort(y+1,y+1+n,cmp2); int ans=0; For(i,n) { ll minY=x[i].y,maxY=minY+C/B; int l=1,r=0,c=0; For(j,n) { ll minX=x[j].x; ll Smax=minX*A+minY*B+C; while(r<n && y[r+1].s<=Smax) { ++r; if (minY<=y[r].y && y[r].y<=maxY) ++c; } while(l<=n && x[l].x<minX) { if (minY<=x[l].y && x[l].y<=maxY) --c; ++l; } ans=max(ans,c); } } cout<<ans<<endl; return 0; }
相关文章推荐
- 【BZOJ1071】【SCOI2007】组队 利用单调性的双指针
- BZOJ 1071 [SCOI2007]组队
- 【BZOJ1071】【SCOI2007】组队 利用单调性的双指针
- bzoj1071 [SCOI2007]组队
- bzoj1071: [SCOI2007]组队
- [BZOJ1071][SCOI2007][堆]组队
- 【bzoj1071】[SCOI2007]组队
- [BZOJ]1071: [SCOI2007]组队 STL优先队列
- 【bzoj1071】[SCOI2007]组队
- 【SCOI2007】【BZOJ1071】组队
- BZOJ 1071: [SCOI2007]组队【单调性扫一遍
- 【BZOJ1071】[SCOI2007]组队
- bzoj1071 [SCOI2007]组队
- bzoj 1071: [SCOI2007]组队 (单调性乱搞)
- [单调队列] BZOJ 1071 [SCOI2007]组队
- bzoj1071[SCOI2007]组队
- bzoj1071: [SCOI2007]组队
- BZOJ1071 [SCOI2007]组队
- BZOJ1071 [SCOI2007]组队
- bzoj 1071 [SCOI2007]组队 单调性