把每件物品当成平面上一个点,将第一件物品放在原点。那个权重值相当于一条直线,于是相当于直线绕原点转一圈,统计上侧点的数量。
队友的代码:
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int xx,yy,n,num,minans,maxans,tx,ty,same,nowans; struct node{ int x,y,type; }a[100005],b[100005]; bool cmp1(node a,node b) { return a.x>b.x; } bool cmp2(node a,node b) { return a.y>b.y; } bool cmp3(node a,node b) { int yy1=a.y-yy;int yy2=b.y-yy; int xx1=a.x-xx;int xx2=b.x-xx; return yy1*xx2>yy2*xx1; } void ok(int p) { minans=min(minans,p); maxans=max(maxans,p); } bool samer(int u,int v) { return (a[u].x-xx)*(a[v].y-yy)==(a[u].y-yy)*(a[v].x-xx); } int main() { minans=99999999; maxans=-1; scanf("%d",&n); scanf("%d%d",&xx,&yy); b[1].x=xx; b[1].y=yy; for(int i=2;i<=n;++i) { scanf("%d%d",&tx,&ty); b[i].x=tx; b[i].y=ty; if(tx>xx&&ty>yy) { } else if(tx<xx&&ty<yy) { } else if(tx<xx&&ty>yy) { a[++num].x=xx+(xx-tx); a[num].y=yy-(ty-yy); a[num].type=1; } else if(tx>xx&&ty<yy) { a[++num].x=tx; a[num].y=ty; a[num].type=2; } else if(tx==xx&&ty==yy) { same++; } } sort(b+1,b+n+1,cmp1); for(int i=1;i<=n;++i) if(b[i].x==xx) { ok(i); } sort(b+1,b+n+1,cmp2); for(int i=1;i<=n;++i) if(b[i].y==yy) { ok(i); } sort(a+1,a+num+1,cmp3); if(!num) { printf("%d %d",minans,maxans); return 0; } nowans=0; for(int i=1;i<=n;++i) if(b[i].x!=xx||b[i].y!=yy) { if(b[i].y==yy) { if(b[i].x>xx) nowans++; } else if(b[i].y>yy) nowans++; } int l=1,r=1; while(l<=num) { while(samer(l,r+1)&&r<num) { r++; } int now1=0,now2=0; for(int i=l;i<=r;++i) { if(a[i].type==1) now1++; else now2++; } ok(nowans+now2+same+1); ok(nowans-now1+1); nowans+=now2; nowans-=now1; l=r+1; r=l; } printf("%d %d",minans,maxans); return 0; }