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; }
It is your time to fight!