zoukankan      html  css  js  c++  java
  • 【日常训练】【CF】20200608_干扰_CF575E_计算几何

    题面

    题解

    现场得分:85/100

    因为我一开始加边的时候,打错了16个坐标之一。

    • 这题实在没什么的
    • 我们发现每一个碎片的范围都是一个多边形,我们最终的三角形的顶点总归在某一个多边形的顶点上,总归会有一个三角形覆盖了所有多边形。
    • 所以那个期望其实就是假的,你现在只要求覆盖了所有多边形的最大的外接圆。
    • 我们发现三个顶点肯定都在所有多边形的所有顶点组成的凸包上
    • 我们又发现三个顶点一定是在凸包上连续的
    • 我们还发现满足上述要求的最大的外接圆一定覆盖了整个凸包(这个我当时没有证出来,但是我认为它是对的)
    • 事实上,外接圆半径用正弦定理求最简单

    代码

    #include<bits/stdc++.h>
    #define LL long long
    #define eps 0.00000000001
    #define MAXAI 100000
    #define MAXN 100000
    #define double long double
    using namespace std;
    template<typename T>void Read(T &cn)
    {
    	char c; int sig = 1;
    	while(!isdigit(c = getchar())) if(c == '-') sig = -1; cn = c-48;
    	while(isdigit(c = getchar())) cn = cn*10+c-48; cn*=sig;
    }
    template<typename T>void Write(T cn)
    {
    	if(cn < 0) {putchar('-'); cn = 0-cn; }
    	int wei = 0; T cm = 0; int cx = cn%10; cn/=10;
    	while(cn) wei++, cm = cm*10+cn%10, cn/=10;
    	while(wei--) putchar(cm%10+48), cm /= 10;
    	putchar(cx+48);
    }
    template<typename T>void Max(T &cn, T cm) {cn = cn < cm ? cm : cn; }
    template<typename T>void Min(T &cn, T cm) {cn = cn < cm ? cn : cm; }
    struct dian2{
    	double x,y;
    	inline friend dian2 operator +(dian2 a, dian2 b) {dian2 guo; guo.x = a.x+b.x; guo.y = a.y+b.y; return guo; }
    	inline friend dian2 operator -(dian2 a, dian2 b) {dian2 guo; guo.x = a.x-b.x; guo.y = a.y-b.y; return guo; }
    //	void outit() {printf("%f %f
    ",(float)x,(float)y); }
    };
    struct dian{
    	int x,y;
    	void mk(int cn, int cm) {x = cn; y = cm; }
    	inline friend bool operator <(dian a, dian b) {return a.x == b.x ? a.y < b.y : a.x < b.x; }
    	inline friend dian operator +(dian a, dian b) {dian guo; guo.x = a.x+b.x; guo.y = a.y+b.y; return guo; }
    	inline friend dian operator -(dian a, dian b) {dian guo; guo.x = a.x-b.x; guo.y = a.y-b.y; return guo; }
    	void outit() {printf("%d %d
    ",x,y); }
    };
    struct xian{
    	dian2 A, B;
    };
    dian a[MAXN*16+1];
    int alen;
    int n;
    int zhan[MAXN*16+1];
    int zlen1, zlen2;
    double ansr;
    int ansA, ansB, ansC;
    dian mk(int cn, int cm) {dian guo; guo.mk(cn, cm); return guo; }
    void zeng(int cn, int cm) {if(0<=cn && cn<=MAXAI && 0<=cm && cm<=MAXAI) a[++alen].mk(cn,cm); }
    LL chaji(dian A, dian B, dian C)
    {
    	LL dx1 = B.x-A.x, dx2 = C.x-A.x;
    	LL dy1 = B.y-A.y, dy2 = C.y-A.y;
    	return dx1*dy2-dx2*dy1;
    }
    dian2 zh(dian A, dian B) {dian2 guo; guo.x = (A.x+B.x)/2.0; guo.y = (A.y+B.y)/2.0; return guo; }
    dian2 zhuan(dian A) {dian2 guo; guo.x = -A.y; guo.y = A.x; return guo; }
    dian2 jiao(xian L1, xian L2)
    {
    	double kB = (L1.A.x*L1.B.y - L1.B.x*L1.A.y + L2.A.y*L1.B.x - L2.A.x*L1.B.y)/(L2.B.x*L1.B.y - L2.B.y*L1.B.x);
    	dian2 guo; guo.x = L2.A.x + kB*L2.B.x; guo.y = L2.A.y + kB*L2.B.y;
    	return guo;
    }
    dian2 suan_O(dian A, dian B, dian C)
    {
    //	printf("in suan_O :
    ");
    //	A.outit(); B.outit(); C.outit();
    	xian L1, L2;
    	L1.A = zh(A, B); L1.B = zhuan(A-B); 
    	L2.A = zh(B, C); L2.B = zhuan(B-C);
    	dian2 guo = jiao(L1, L2);
    //	guo.outit();
    	return guo;
    }
    double suan_jlf(dian2 A, dian B) {return (A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y); }
    int pan(dian2 A, double R)
    {
    	if(zlen2 >= 4000) return 1;
    	for(int i = 1;i<=zlen2;i++) if(suan_jlf(A, a[zhan[i]]) - R >= eps) return 0;
    	return 1;
    }
    void jian(int cn, int cm, int cx)
    {
    	if(chaji(a[cn], a[cm], a[cx]) == 0) return;
    	dian2 linO = suan_O(a[cn], a[cm], a[cx]);
    	double linr = suan_jlf(linO, a[cn]);
    	if(linr <= ansr) return;
    	if(pan(linO, linr)) ansr = linr, ansA = cn, ansB = cm, ansC = cx;
    }
    int main()
    {
    //	freopen("emi.in","r",stdin);
    //	freopen("emi.out","w",stdout);
    //	suan_O(mk(0,0), mk(1,2), mk(2,1));
    	Read(n); alen = 0;
    	for(int i = 1;i<=n;i++) 
    	{
    		int bx,by,bz; Read(bx); Read(by); Read(bz);
    		zeng(bx-bz, by); zeng(bx+bz, by);
    		zeng(bx, by-bz); zeng(bx, by+bz);
    		
    		if(bx+by <= bz) zeng(0, 0);
    		if(bx+MAXAI-by <= bz) zeng(0, MAXAI);
    		if(MAXAI-bx+by <= bz) zeng(MAXAI, 0);
    		if(MAXAI-bx+MAXAI-by <= bz) zeng(MAXAI, MAXAI);
    		
    		if(bx < bz) zeng(0, by-(bz-bx)), zeng(0, by+(bz-bx));
    		if(by < bz) zeng(bx-(bz-by), 0), zeng(bx+(bz-by), 0);
    		if(MAXAI-bx < bz) zeng(MAXAI, by+(bz+bx-MAXAI)), zeng(MAXAI, by-(bz+bx-MAXAI));
    		if(MAXAI-by < bz) zeng(bx+(bz+by-MAXAI), MAXAI), zeng(bx-(bz+by-MAXAI), MAXAI);
    	}
    	sort(a+1, a+alen+1);
    	zlen1 = 2; zhan[1] = 1; zhan[2] = 2;
    	for(int i = 3;i<=alen;i++)
    	{
    		while(zlen1 >= 2 && chaji(a[zhan[zlen1-1]], a[zhan[zlen1]], a[i]) <= 0) zlen1--;
    		zhan[++zlen1] = i;
    	}
    	zlen2 = zlen1+1; zhan[zlen2] = alen-1;
    	for(int i = alen-2;i>=1;i--)
    	{
    		while(zlen2-zlen1 >= 1 && chaji(a[zhan[zlen2-1]], a[zhan[zlen2]], a[i]) <= 0) zlen2--;
    		zhan[++zlen2] = i;
    	}
    	ansr = 0;
    	jian(zhan[zlen2-1], zhan[1], zhan[2]);
    	for(int i = 1;i<=zlen2-2;i++) jian(zhan[i], zhan[i+1], zhan[i+2]);
    	a[ansA].outit(); a[ansB].outit(); a[ansC].outit();
    	return 0;
    }
    
  • 相关阅读:
    未处理的异常 stack overflow
    Largest Rectangle in a Histogram [POJ2559] [单调栈]
    Blocks [POJ3734] [矩阵快速幂]
    Rectangular Covering [POJ2836] [状压DP]
    Arrange the Bulls [POJ2441] [状压DP]
    The Water Bowls [POJ3185] [开关问题]
    Bound Found [POJ2566] [尺取法]
    4 Values whose Sum is 0 [POJ2785] [折半搜索]
    Physics Experiment 弹性碰撞 [POJ3684]
    Fliptile [POJ3279] [开关问题]
  • 原文地址:https://www.cnblogs.com/czyarl/p/13067256.html
Copyright © 2011-2022 走看看