[POJ2954&POJ1265]皮克定理的应用两例

皮克定理:

  在一个多边形中。用I表示多边形内部的点数,E来表示多边形边上的点数,S表示多边形的面积。

  满足:S:=I+E/2-1;

解决这一类题可能运用到的:

  求E,一条边(x1,y1,x2,y2)上的点数(包括两个顶点)=gcd(abs(x1-x2),abs(y1-y2))+1;

  求S:刚开始做POJ2954的时候莫名其妙一直WA,用了海伦公式求面积,后来又改用割补法,还是WA。发现面积还是用叉积算的好。

在八十中走廊里看过的书都忘光了啊...这么典型的叉积运用都会选择小学方法...不过至今没弄明白为什么海伦公式和割补法的误差那么大...


POJ2954 

 1 program poj2954;
 2 var x1,y1,x2,y2,x3,y3,e:longint;
 3       s:extended;
 4 
 5 function gcd(x,y:longint):longint;
 6 begin
 7     if y=0 then exit(x) else
 8     exit(gcd(y,x mod y));
 9 end;
10 
11 function calc_area(x1,y1,x2,y2,x3,y3:longint):extended;
12 begin
13     exit(abs((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1))/2);
14 end;
15 
16 function solve(x1,y1,x2,y2:longint):longint;
17 begin
18     exit(gcd(abs(x1-x2),abs(y1-y2))+1);
19 end;
20 
21 begin
22     //assign(input,'poj2954.in');reset(input);
23     //assign(output,'a.out');rewrite(output);
24     while not eof do 
25     begin
26         readln(x1,y1,x2,y2,x3,y3);
27         if (x1=0)and(y1=0)and(x2=0)and(y2=0)and(x3=0)and(y3=0) then halt;
28         s:=calc_area(x1,y1,x2,y2,x3,y3);                
29         e:=solve(x1,y1,x2,y2)+solve(x1,y1,x3,y3)+solve(x2,y2,x3,y3)-3;
30         writeln(trunc(s-e/2+1));
31     end;
32 end.

POJ1265

 1 program poj1265;
 2 const maxn=110;
 3 type point=record x,y:longint;end;
 4 var t,test,n,e,i,tx,ty:longint;
 5       s:extended;
 6       a:array[-1..maxn]of point;
 7 
 8 function gcd(x,y:longint):longint;
 9 begin
10     if y=0 then exit(x) else
11     exit(gcd(y,x mod y));
12 end;
13 
14 function cross(p0,p1,p2:point):double;
15 begin
16     exit((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
17 end;
18 
19 begin
20     //assign(input,'poj1265.in');reset(input);
21     readln(test);
22     for t:=1 to test do 
23     begin
24         readln(n);
25         a[0].x:=0;a[0].y:=0;
26         for i:=1 to n do 
27         begin
28             readln(tx,ty);
29             a[i].x:=a[i-1].x+tx;
30             a[i].y:=a[i-1].y+ty;
31         end;
32         e:=0;
33         for i:=0 to n-1 do inc(e,gcd(abs(a[i].x-a[i+1].x),abs(a[i].y-a[i+1].y)));
34         s:=0;
35         for i:=2 to n do s:=s+cross(a[0],a[i-1],a[i])/2;
36         s:=abs(s);
37         writeln('Scenario #',t,':');
38         writeln(trunc(s+1-e/2),' ',e,' ',s:0:1);
39         writeln;
40     end;
41 end.
原文地址:https://www.cnblogs.com/mjy0724/p/4372732.html