POJ 1265 Pcik定理

题意:

求多边形内部整点的个数、边上整点数、多边形的面积(点数指正点数)

 

题解:

[Pick定理] 设以整数点为顶点的多边形的面积为S, 多边形内部的整数点数为N, 多边形边界上的整数点数为L, 则 N + L/2 - 1 = S

 

 

View Code
 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cstdio>
 5 #include <algorithm>
 6 #include <cmath>
 7 
 8 #define N 222
 9 
10 using namespace std;
11 //[Pick定理] 设以整数点为顶点的多边形的面积为S, 多边形内部的整数点数为N, 多边形边界上的整数点数为L, 则 N + L/2 - 1 = S
12 struct PO
13 {
14     int x,y;
15 }p[N];
16 
17 int n,gs;
18 
19 inline void read()
20 {
21     scanf("%d",&n);
22     for(int i=1,a=0,b=0,c,d;i<=n;i++)
23     {
24         scanf("%d%d",&c,&d);
25         a+=c; b+=d;
26         p[i].x=a; p[i].y=b;
27     }
28 }
29 
30 inline int cross(PO &a,PO &b,PO &c)
31 {
32     return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
33 }
34 
35 inline int gcd(int a,int b)
36 {
37     int ys;
38     while(b)
39     {
40         ys=a%b;
41         a=b; b=ys;
42     }
43     return a;
44 }
45 
46 inline int getnum(PO &a,PO &b)
47 {
48     int x=abs(a.x-b.x),y=abs(a.y-b.y);
49     return gcd(x,y)-1;
50 }
51 
52 inline int getarea()
53 {
54     int ans=0;
55     for(int i=1;i<=n;i++) ans+=cross(p[0],p[i],p[i+1]);
56     return ans;
57 }
58 
59 inline void go()
60 {
61     p[n+1]=p[1];
62     int edgenum=n;
63     for(int i=1;i<=n;i++) edgenum+=getnum(p[i],p[i+1]);
64     int area=abs(getarea());
65     int innum=(area-edgenum)/2+1;
66     printf("Scenario #%d:\n",++gs);
67     printf("%d %d %.1lf\n\n",innum,edgenum,area*0.5);
68 }
69 
70 int main()
71 {
72     int cas; scanf("%d",&cas);
73     while(cas--) read(),go();
74     return 0;
75 }

 

 

posted @ 2013-02-24 19:00  proverbs  阅读(212)  评论(0编辑  收藏  举报