zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营 第二场 B Boundary 计算几何 圆 已知三点求圆心

    LINK:Boundary

    计算几何确实是弱项 因为好多东西都不太会求 没有到很精通的地步。

    做法很多,先说官方题解

    其实就是枚举一个点 P 然后可以发现 再枚举一个点 然后再判断有多少个点在圆上显然会超时。

    直接考虑求出所有点和(O,P)的夹角 因为同弧所对圆周角相等 最后统计有多少个角度相等来做。

    一个误区是 两个对称的圆上的点被算在一起了 此时强制利用 第三个点在所在直线的左侧/右侧来消除影响。

    正确性显然。复杂度(n^2cdot logn)

    一个比较好想好写的做法:

    枚举到第三个点的时候就不能再统计有多少个点在这个圆上了 然后 考虑答案的圆的圆心一定是被重复计算出次数最多的。

    所以可以得到某个圆心被计算次数最多的数量 反推出点数即可。

    一个难点 已知三点求圆心 这好像是一个模板 不过推导需要利用 克莱姆法则及矩阵行列式的知识来推 这我肯定式推不出来滴 而且公式挺难背的!~

    code
    //#include<bitsstdc++.h>
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<ctime>
    #include<cmath>
    #include<cctype>
    #include<cstdlib>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<vector>
    #include<algorithm>
    #include<utility>
    #include<bitset>
    #include<set>
    #include<map>
    #define ll long long
    #define db double
    #define INF 10000000000000000ll
    #define ldb long double
    #define pb push_back
    #define put_(x) printf("%d ",x);
    #define get(x) x=read()
    #define gt(x) scanf("%d",&x)
    #define gi(x) scanf("%lf",&x)
    #define put(x) printf("%d
    ",x)
    #define putl(x) printf("%lld
    ",x)
    #define gc(a) scanf("%s",a+1)
    #define rep(p,n,i) for(RE int i=p;i<=n;++i)
    #define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
    #define fep(n,p,i) for(RE int i=n;i>=p;--i)
    #define vep(p,n,i) for(RE int i=p;i<n;++i)
    #define pii pair<int,int>
    #define mk make_pair
    #define RE register
    #define P 1000000007
    #define gf(x) scanf("%lf",&x)
    #define pf(x) ((x)*(x))
    #define uint unsigned long long
    #define ui unsigned
    #define EPS 1e-6
    #define sq sqrt
    #define S second
    #define F first
    #define mod 1000000007
    #define V vector
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
        return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
        RE int x=0,f=1;RE char ch=getc();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
        return x*f;
    }
    const int MAXN=2010;
    int n,flag;db w1,w2;
    struct wy
    {
    	db x,y;
    }t[MAXN];
    V<pair<db,db> >g;
    int pd(db x,db y){return fabs(x-y)<=EPS;}
    inline void calc(wy a,wy b,wy c)
    {
    	flag=0;
    	db D1=2*(a.y-c.y)*(a.x-b.x)-2*(a.y-b.y)*(a.x-c.x);
    	db D2=2*(a.y-b.y)*(a.x-c.x)-2*(a.y-c.y)*(a.x-b.x);
    	if(pd(D1,0)||pd(D2,0)){flag=1;return;}
    	db W1=pf(a.x)-pf(b.x)+pf(a.y)-pf(b.y);
    	db W2=pf(a.x)-pf(c.x)+pf(a.y)-pf(c.y);
    	w1=(W1*(a.y-c.y)-W2*(a.y-b.y))/D1;
    	w2=(W1*(a.x-c.x)-W2*(a.x-b.x))/D2;
    }
    int main()
    {
    	//freopen("1.in","r",stdin);
    	get(n);
    	rep(1,n,i)get(t[i].x),get(t[i].y);
    	rep(1,n,i)rep(i+1,n,j)
    	{
    		calc((wy){0,0},t[i],t[j]);
    		if(flag)continue;
    		g.pb(mk(w1,w2));
    	}
    	if(g.size()==0){puts("1");return 0;}
    	sort(g.begin(),g.end());
    	int mx=1,cnt=1;pair<db,db>ww=g[0];
    	vep(1,g.size(),i)
    	{
    		if(pd(ww.F,g[i].F)&&pd(ww.S,g[i].S))++cnt,mx=max(mx,cnt);
    		else ww=g[i],cnt=1;
    	}
    	int cc=(1+(int)sqrt(1+1.0*8*mx))/2;
    	put(cc);return 0;
    }
    
  • 相关阅读:
    利用 runtime,解决多次点击相同 button,导致重复跳转的问题-b
    dbcp数据库连接池管理
    dbutil组件的常见用法
    事务的概念及常用方法
    jdbc链接基础
    MySQL数据约束和关联查询
    mysql基本操作语句
    jsp常用标签和标签库及javaBean规范
    EL表达式
    会话过程保存数据对象cookie和session
  • 原文地址:https://www.cnblogs.com/chdy/p/13300161.html
Copyright © 2011-2022 走看看