UVAlive 3695 Distant Galaxy 【枚举+扫描线】

传送门
直接枚举四条边界所穿过的点,然后统计点数,这样做的时间复杂度为 O ( n 5 ) O(n^5) O(n5)
考虑部分枚举,即之枚举矩形的上下边界,用其他方法确定左右边界,从左到右扫描即可

#include
using namespace std;
const int N=110;
int n,m,y[N],on[N],on2[N];
int Left[N];
struct point{
	int x,y;
	bool operator <(const point &rhs) const{
		return x<rhs.x;
	}
}p[N];
int solve(){
	sort(p,p+n);
	sort(y,y+n);
	m=unique(y,y+n)-y;
	if(m<=2) return n;
	int ans=0;
	for(int a=0;a<m;a++)
		for(int b=a+1;b<m;b++){
			int ymin=y[a],ymax=y[b];
			
			int k=0;
			for(int i=0;i<n;i++){
				if(i==0||p[i].x!=p[i-1].x){
					k++;
					on[k]=on2[k]=0;
					Left[k]=(k==0?0:Left[k-1]+on2[k-1]-on[k-1]);
				}
				if(p[i].y>ymin&&p[i].y<ymax) on[k]++;
				if(p[i].y>=ymin&&p[i].y<=ymax) on2[k]++;
			}
			if(k<=2) return n;
			int M=0;
			for(int j=1;j<=k;j++){
				ans=max(ans,Left[j]+on2[j]+M);
				M=max(M,on[j]-Left[j]);
			}
		}
		return ans;
} 
int main(){
	int kase=0;
	while(cin>>n,n){
		for(int i=0;i<n;i++){
			cin>>p[i].x>>p[i].y;
			y[i]=p[i].y; 
		}
		printf("Case %d: %d\n",++kase,solve());
	}
} 

你可能感兴趣的:(扫描线,枚举)