题目:http://poj.org/problem?id=1265
题意 : 给你一个点阵,上边有很多点连成的多边形,让你求多边形内部的点和边界上的点以及多边形的面积,要注意他每次给出的点并不是点的横纵坐标,而是相对于上一个点的横纵坐标离开的距离dx,dy,所以你还要求一下每个点的坐标,然后再进行别的操作就可以了
题目解析:
这个题用了很多知识点:
1、以格子点为顶点的线段,覆盖的点的个数为GCD(dx,dy),其中,dxdy分别为线段横向占的点数和纵向占的点数。如果dx或dy为0,则覆盖的点数为dy或dx。
2、Pick公式:平面上以格子点为顶点的简单多边形的面积=边上的点数/2+内部的点数+1。
3、任意一个多边形的面积等于按顺序求相邻两个点与原点组成的向量的叉积之和/2。
#include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> #include <math.h> #include <queue> #define inf 0x3f3f3f3f #define eps 1e-9 typedef long long ll; using namespace std; struct point { int x,y; } q[1010]; int n; ll num,In; double S; int gcd(int A,int B) { return B==0?A:gcd(B,A%B); } int Mult(point A,point B) { return A.x*B.y-B.x*A.y; } int main() { int T,xx,yy,sx,sy,dx,dy,K=0; scanf("%d",&T); while(T--) { scanf("%d",&n); sx=sy=0; S=0; num=0; for(int i=1; i<=n; i++) { scanf("%d%d",&xx,&yy); sx+=xx; sy+=yy; q[i].x=sx; q[i].y=sy; } q[0].x=q[n].x; q[0].y=q[n].y; for(int i=0; i<n; i++) { S+=Mult(q[i],q[i+1]); dx=abs(q[i].x-q[i+1].x); dy=abs(q[i].y-q[i+1].y); num+=gcd(max(dx,dy),min(dx,dy)); } S=fabs(S/2);//不确定S是否为正数 In=int(S)+1-num/2; printf("Scenario #%d: ",++K); printf("%I64d %I64d %.1f ",In,num,S); } return 0; }
代码:
#include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> #include <math.h> #include <queue> #define inf 0x3f3f3f3f #define eps 1e-9 typedef long long ll; using namespace std; struct point { int x,y; } q[1010]; int n; ll num,In; double S; int gcd(int A,int B) { return B==0?A:gcd(B,A%B); } int Mult(point A,point B) { return A.x*B.y-B.x*A.y; } int main() { int T,xx,yy,dx,dy,K=0; scanf("%d",&T); while(T--) { scanf("%d",&n); q[0].x=0; q[0].y=0; S=0; num=0; for(int i=1; i<=n; i++) { scanf("%d%d",&xx,&yy); q[i].x=q[i-1].x+xx; q[i].y=q[i-1].y+yy; } for(int i=0; i<n; i++) { S+=Mult(q[i],q[i+1]); dx=abs(q[i].x-q[i+1].x); dy=abs(q[i].y-q[i+1].y); num+=gcd(max(dx,dy),min(dx,dy)); } S=fabs(S/2);//不确定S是否为正数 In=int(S)+1-num/2; printf("Scenario #%d: ",++K); printf("%I64d %I64d %.1f ",In,num,S); } return 0; }