• CF1025F Disjoint Triangles 题解


    Codeforces
    Luogu

    Description.

    (n) 个点,求有多少对三角形不相交。

    Solution.

    太妙了,没想到,想到三角形对数是 (O(n^6)) 的,发现怎么枚举都不行。

    考虑两个不相交的三角形,我们可以确定它们有恰好两条公切线,使得两个三角形在切线异侧。
    所以我们可以直接枚举公切线,然后再在左边选两个点,右边选两个点,可以直接组合数。
    公切线两侧的点数可以通过极角排序求出。
    每个三角形会被一条公切线少算两次,因为公切线上两个点有 (dbinom 21) 的方案。
    每条公切线会被多算两次,因为公切线会被它两个点分别确定一次。
    刚好抵消。

    Coding.

    点击查看代码
    //Coded by leapfrog on 2021.11.04 {{{
    //是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),f=0;
    	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
    	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	f?x=-x:x;
    }
    template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
    const int N=2005;const long double Pi=acos(-1),eps=1e-9;
    int n,px[N],py[N];ll rs=0;long double an[N*2];
    inline ll C(ll a) {return 1ll*a*(a-1)/2;}
    int main()
    {
    	read(n);for(int i=1;i<=n;i++) read(px[i],py[i]);
    	for(int k=1,at=0;k<=n;k++,at=0)
    	{
    		for(int i=1;i<=n;i++) if(k^i) an[++at]=atan2(py[i]-py[k],px[i]-px[k]);
    		sort(an+1,an+at+1);for(int i=1;i<n;i++) an[++at]=an[i]+Pi*2;
    		for(int i=1,j=1;i<n;i++)
    		{
    			while(an[j]-an[i]<=Pi) j++;
    			int l=j-i-1,r=n-2-l;rs+=1ll*C(l)*C(r);
    		}
    	}return printf("%lld
    ",rs>>1),0;
    }
    
  • 相关阅读:
    01:求平均年龄
    09:与圆相关的计算
    08:温度表达转化
    07:计算多项式的值
    06:甲流疫情死亡率
    05:计算分数的浮点数值
    04:带余除法
    03:计算(a+b)/c的值
    02:计算(a+b)*c的值
    01:A+B问题
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15511502.html
Copyright © 2020-2023  润新知