Live2d Test Env

Gym 101142 I.Integral Polygons(计算几何)

题意:给定一个凸包,现在让你连接凸包上两点,把凸包变为两个多边形,满足两个多边形的面积都是整数。

思路:我们知道整点的三角形面积S=叉积/2,则S要么是整数,要么是整数+0.5。那么多边形有多个三角形组成=So01+So12+So23+...(o是原点),也有这样的性质。因此,我们现在在算面积的时候不除2,通过奇偶来判定面积是否是整数。

       首先得到整个凸包的面积,如果是奇数,那么不可能划分位为两个偶数,输出0;

       如果是偶数,那么我们需要统计多少对(j,i),满足i点到j点组成的多边形面积是偶数。 多边形(j,i)的面积为S=Si-Sj-Soij。因为只要求奇偶性,我们用异或^来算加减法即可,而乘法用且&来表示。

      注意累加的是需要减去i和j相邻的情况,即一个线段,面积为0,也是偶数,被累加了,需要减去。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=200010;
int num[2][2][2],x[maxn],y[maxn],area; ll ans;
int main()
{
    int N,i,tx,ty;
    scanf("%d",&N);
    for(i=0;i<N;i++) scanf("%d%d",&x[i],&y[i]);
    x[N]=x[0]; y[N]=y[0];
    for(i=0;i<=N;i++) x[i]=(x[i]%2+2)%2,y[i]=(y[i]%2+2)%2;
    for(i=1;i<=N;i++){
        area^=(x[i]&y[i-1])^(x[i-1]&y[i]);   //多边形的面积 
        for(tx=0;tx<=1;tx++)
         for(ty=0;ty<=1;ty++){
             int t=(tx&y[i])^(ty&x[i]);    //三角形的面积 
             ans+=num[area^t][tx][ty];     //Sarea-S三角形=被割的面积 
        }
        ans--;
        num[area][x[i]][y[i]]++;
    }
    if(area) puts("0");
    else printf("%I64d\n",ans);
    return 0;
}

 

posted @ 2018-08-11 10:54  nimphy  阅读(561)  评论(0编辑  收藏  举报