• [CF gym 101471A][LOJ6470]Airport Construction


    题面

    http://codeforces.com/gym/101471/attachments A题

    题解

    前置知识

    肉眼目测答案线段至少通过两个多边形顶点。

    枚举这两个顶点,判线段是否在多边形内。

    若是,将其两边延长直到碰到多边形的边,然后用延长后的边更新答案。

    代码

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define rg register
    #define In inline
    #define ld long double
    
    const ld eps = 1e-7;
    const int N = 200;
    
    In int read(){
    	int s = 0,ww = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9'){if(ch == '-')ww = -1;ch = getchar();}
    	while('0' <= ch && ch <= '9'){s = 10 * s + ch - '0';ch = getchar();}
    	return s * ww;
    }
    
    In int sgn(ld x){return x < -eps ? -1 : x > eps;}
    
    In ld sqr(ld x){return x * x;}
    
    struct vec{
    	ld x,y;
    	vec(){}
    	vec(ld _x,ld _y){x = _x,y = _y;}
    	In friend vec operator + (vec a,vec b){
    		return vec(a.x + b.x,a.y + b.y);
    	}
    	In friend vec operator - (vec a,vec b){
    		return vec(a.x - b.x,a.y - b.y);
    	}
    	In friend vec operator * (vec a,ld k){
    		return vec(a.x * k,a.y * k);
    	}
    	In friend vec operator / (vec a,ld k){
    		return vec(a.x / k,a.y / k);
    	}
    	In friend ld Dot(vec a,vec b){
    		return a.x * b.x + a.y * b.y;
    	}
    	In friend ld Cross(vec a,vec b){
    		return a.x * b.y - a.y * b.x;
    	}
    	In friend bool InUpper(vec a){
    		return sgn(a.y) > 0 || (sgn(a.y) == 0 && sgn(a.x) > 0);
    	}
    	In friend bool prl(vec a,vec b){
    		return sgn(Cross(a,b)) == 0;
    	}
    	In friend bool samedir(vec a,vec b){
    		return prl(a,b) && sgn(Dot(a,b)) >= 0;
    	}
    	In friend ld len(vec a){
    		return sqrt(sqr(a.x) + sqr(a.y));
    	}
    };
    
    struct seg{
    	vec p,q;
    	seg(){}
    	seg(vec _p,vec _q){p = _p,q = _q;}
    	In friend bool prl(seg a,seg b){
    		return prl(a.q - a.p,b.q - b.p);
    	}
    	In friend bool samedir(seg a,seg b){
    		return samedir(a.q - a.p,b.q - b.p);
    	}
    	In friend bool OnSeg(seg a,vec p){
    		return samedir(p - a.p,a.q - a.p) && samedir(p - a.q,a.p - a.q);
    	}
    	In friend vec Its(seg a,seg b){
    		ld x = Cross(b.q - b.p,a.p - b.p);
    		ld y = Cross(a.q - a.p,b.q - b.p);
    		return a.p + (a.q - a.p) * x / y;
    	}
    };
    
    vec p[N+5];
    seg a[N+5],t[N+5];
    int n;
    ld ans;
    
    In bool cmp(seg a,seg b){
    	int k = sgn(Cross(a.q-a.p,b.q-b.p));
    	if(k != 0)return k > 0;
    	return len(a.q - a.p) < len(b.q - b.p);
    }
    
    bool inside(vec p,seg a[],int n){ //2:in,1:on,0:out
    	bool rt = 0;
    	for(rg int i = 1;i <= n;i++){
    		seg s = a[i];
    		if(OnSeg(s,p))return 1;
    		if(sgn(s.p.y-s.q.y) < 0)swap(s.p,s.q);
    		if(sgn(p.y-s.p.y) >= 0 || sgn(p.y-s.q.y) < 0)continue;
    		rt ^= (sgn(Cross(s.p-p,s.q-p)) > 0);
    	}
    	return rt << 1;
    }
    
    vec P[N+5];
    int Pn;
    
    In bool cmp2(vec a,vec b){
    	return a.x == b.x ? a.y < b.y : a.x < b.x;
    }
    
    void check(seg s,seg a[],int n){
    	Pn = 0;
    	for(rg int i = 1;i <= n;i++){
    		if(prl(s,a[i]))continue;
    		vec p = Its(s,a[i]);
    		if(OnSeg(a[i],p))P[++Pn] = p;
    	}
    	if(Pn)sort(P + 1,P + Pn + 1,cmp2);
    	int l = 1,r = 0;
    	while(l < Pn && !OnSeg(s,P[l]))l++;
    	r = l;
    	while(r < Pn && OnSeg(s,P[r+1]))r++;
    	for(rg int i = l;i < r;i++)
    		if(!inside((P[i]+P[i+1])/2,a,n))return;
    	while(l > 1 && inside((P[l-1]+P[l])/2,a,n))l--;
    	while(r < Pn && inside((P[r+1]+P[r])/2,a,n))r++;
    	ans = max(ans,len(P[r]-P[l]));
    }
    
    int main(){
    	n = read();
    	for(rg int i = 1;i <= n;i++){
    		int x = read(),y = read();
    		p[i] = vec(x,y);
    	}	
    	for(rg int i = 1;i < n;i++)a[i] = seg(p[i],p[i+1]);
    	a[n] = seg(p[n],p[1]);
    	for(rg int i = 1;i <= n;i++){
    		int cur = 0;
    		for(rg int j = 1;j <= n;j++){
    			if(i == j || InUpper(p[j]-p[i]))continue;
    			t[++cur] = seg(p[i],p[j]);
    		}
    		sort(t + 1,t + cur + 1,cmp);
    		for(rg int j = 1;j <= cur;j++){
    			if(j > 1 && samedir(t[j-1],t[j]))continue;
    			check(t[j],a,n);
    		}
    	}
    	printf("%.9lf
    ",(double)ans);
    	return 0;
    }
    
  • 相关阅读:
    继承与多态
    String作业
    课后作业及动手动脑
    作业3
    动手动脑
    实验任务四
    动手动脑
    课堂练习01
    《大道至简》第一章读后感伪代码
    C++常用编程关键字
  • 原文地址:https://www.cnblogs.com/xh092113/p/12350026.html
Copyright © 2020-2023  润新知