ZOJ 2967 Colorful Rainbows
暴力。
先删掉一些边,平行的线只保留$b$最大的。然后暴力,每次放入第$i$条边,和还没有被完全覆盖的边都算一遍,更新一下。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<ctime> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0); void File() { freopen("D:\\in.txt","r",stdin); freopen("D:\\out.txt","w",stdout); } template <class T> inline void read(T &x) { char c = getchar(); x = 0; while(!isdigit(c)) c = getchar(); while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } } double INF=999999999999999.0; #define eps 1e-8 #define zero(x) (((x)>0?(x):-(x))<eps) struct point { double x,y; }; struct line { point a,b; double K,B; double ll,rr; } L[6000],tmp[6000]; int T,n; int f[6000]; bool cmp(line a,line b) { if(a.K!=b.K) return a.K>b.K; return a.B>b.B; } point intersection(point u1,point u2,point v1,point v2) { point ret=u1; double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x)) /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x)); ret.x+=(u2.x-u1.x)*t; ret.y+=(u2.y-u1.y)*t; return ret; } int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0; i<n; i++) scanf("%lf%lf",&tmp[i].K,&tmp[i].B); sort(tmp,tmp+n,cmp); int sz=0; L[sz++]=tmp[0]; for(int i=1; i<n; i++) { if(abs(L[sz-1].K-tmp[i].K)<eps) continue; L[sz++]=tmp[i]; } for(int i=0; i<sz; i++) { point p1; p1.x=1; p1.y=L[i].K*1+L[i].B; point p2; p2.x=-1; p2.y=L[i].K*(-1)+L[i].B; L[i].a=p1, L[i].b=p2; L[i].ll=-INF, L[i].rr=INF; } memset(f,0,sizeof f); for(int i=1; i<sz; i++) { for(int j=0; j<i; j++) { if(f[j]) continue; point jiao = intersection(L[i].a,L[i].b,L[j].a,L[j].b); if(L[i].K>=0&&L[i].K>L[j].K) { L[i].ll=max(L[i].ll,jiao.x); L[j].rr=min(L[j].rr,jiao.x); } else if(L[i].K>=0&&L[i].K<L[j].K) { L[i].rr=min(L[i].rr,jiao.x); L[j].ll=max(L[j].ll,jiao.x); } else if(L[i].K<0&&L[j].K>L[i].K) { L[i].rr=min(L[i].rr,jiao.x); L[j].ll=max(L[j].ll,jiao.x); } else if(L[i].K<0&&L[j].K<L[i].K) { L[i].ll=max(L[i].ll,jiao.x); L[j].rr=min(L[j].rr,jiao.x); } if(L[i].rr<=L[i].ll+eps) f[i]=1; if(L[j].rr<=L[j].ll+eps) f[j]=1; } } int ans=0; for(int i=0; i<sz; i++) if(f[i]==0) ans++; printf("%d\n",ans); } return 0; }