zoukankan      html  css  js  c++  java
  • CF13D Triangles

    这是一道需要数学知识的(DP?)

    Idea

    首先,如何判断一个点是否在该三角形内 —— 我们假定(igtriangleup ABC)以及所要判断的点(P),如果(P)(ABC)内,那么对边(AB)来说,点(P)和点(C)在边(AB)的同侧;对边(BC)来说,点(P)和点(A)在边BC的同侧,同样,边(AC)也是如此。我们可以用叉积来实现这个想法,叉积(>0)为同侧,叉积(<0)为异侧。

    我们设一个原点(O)(其坐标应在输入范围以外),每次在红点中找两个点,求这两个点与(O)组成的三角形中有多少个蓝点,用(dp[i][j])保存下来;

    我们假设在红点中选三个点组成三角形,标记为(ABC),那么

    (igtriangleup ABC ext{内蓝点个数} = igtriangleup OAB + igtriangleup OBC - igtriangleup OAC)

    Code

    记得开(long~long),否则连样例都过不去

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #include<string>
    #include<queue>
    #define int long long
    #define maxn 505
    #define inf 2147483647
    #define mod 998244353
    #define eps 1e-6
    #define pi acos(-1.0)
    #define de(x) ((x)*(x))
    using namespace std; 
    inline int read(){
        int x=0,f=1; char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-48;ch=getchar();}
        return x*f;
    }
    int dp[maxn][maxn];
    struct Node{
        int x, y;
        Node() {}
        Node(int xi, int yi):x(xi), y(yi){}
        Node operator - (const Node &N) const{return Node(x-N.x, y-N.y);}
        inline int operator * (const Node &N) const{return x*N.y-y*N.x;}
    }red[maxn],blue[maxn];
    signed main(){
        int n=read(),m=read();
        for(int i=0;i<n;i++) red[i].x=read(),red[i].y=read();
        for(int i=0;i<m;i++) blue[i].x=read(),blue[i].y=read();
        Node a=Node(-1000000001,-1000000001);
        for(int i=0;i<n;i++)
        for(int j=0;j<n;j++){
            if((red[i]-a)*(red[j]-a)<=0) continue;
            for(int k=0;k<m;k++){
                if((red[i]-a)*(blue[k]-a)>0&&(red[j]-red[i])*(blue[k]-red[i])>0&&(a-red[j])*(blue[k]-red[j])>0)
                    dp[i][j]++;
            }
            dp[j][i]=-dp[i][j];
        }
        int ans=0;
        for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)
        for(int k=j+1;k<n;k++)
        ans+=(dp[i][j]+dp[j][k]+dp[k][i]==0);
        printf("%d",ans);
        return 0;
    }
    
  • 相关阅读:
    超神头文件
    世界上还有比二分更容易错的算法吗?
    【POJ 1734】Sightseeing trip
    P1303 A*B Problem
    P1601 A+B Problem(高精)
    P1051 谁拿了最多奖学金
    【P1025】数的划分
    P1005 矩阵取数游戏
    P1006 传纸条
    邮票问题
  • 原文地址:https://www.cnblogs.com/cbyyc/p/11483246.html
Copyright © 2011-2022 走看看