容易发现答案只与w1和w2的比值有关,而与具体数值无关
那么先特殊算一下w1=0和w2等于0的情况,然后就直接假设w1=1
然后的话对于每个物品可能有4种情况:永远比1号优,永远比1号劣,永远和1号相等,当w2<某值时比1号优,等于时相等,否则比一号劣,或者当w2>某值时比1号劣,等于时相等,否则比1号优
对于每个手机算一下他的情况和w2的分界点,然后按分界点排序之后扫一遍即可
比赛的时候有个地方x和y打反一直wa,然后就弃疗了
#include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<ctime> #include<cmath> #include<algorithm> #include<iomanip> #include<queue> #include<map> #include<bitset> #include<stack> #include<vector> #include<set> using namespace std; #define MAXN 100010 #define MAXM 1010 #define INF 1000000000 #define MOD 1000000007 #define ll long long #define eps 1e-8 struct data{ double v; int c; friend bool operator <(data x,data y){ return x.v<y.v; } }; int n; int x[MAXN],y[MAXN]; int low=1,high=INF; data t[MAXN]; int tot; int main(){ int i; scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%d%d",&x[i],&y[i]); } int tlowx=1,thighx=1,tlowy=1,thighy=1; for(i=2;i<=n;i++){ if(x[i]>x[1]){ thighx++; } if(x[i]>=x[1]){ tlowx++; } if(y[i]>y[1]){ thighy++; } if(y[i]>=y[1]){ tlowy++; } } low=max(low,max(tlowx,tlowy)); high=min(high,min(thighx,thighy)); int tlow=1,thigh=1; for(i=2;i<=n;i++){ if(y[i]==y[1]){ if(x[i]>=x[1]){ tlow++; } if(x[i]>x[1]){ thigh++; } continue ; } if(y[i]<y[1]){ t[++tot].v=1000.*(x[1]-x[i])/(y[i]-y[1]); t[tot].c=-1; tlow++; thigh++; } if(y[i]>y[1]){ t[++tot].v=1000.*(x[1]-x[i])/(y[i]-y[1]); t[tot].c=1; } if(t[tot].v<=0){ tlow+=t[tot].c; thigh+=t[tot].c; tot--; } } if(tot){ sort(t+1,t+tot+1); for(i=1;i<=tot;){ int wzh=i; int tc0=0,tc1=0; while(wzh<=tot&&fabs(t[wzh].v-t[i].v)<eps){ if(t[wzh].c==1){ tc1++; }else{ tc0++; } wzh++; } low=max(low,tlow+tc1); high=min(high,thigh-tc0); tlow+=tc1-tc0; thigh+=tc1-tc0; i=wzh; } } printf("%d %d\n",high,low); return 0; } /* 2 3 2 1 2 */