皮克定理:

  在一个多边形中。用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 

 program poj2954;
var x1,y1,x2,y2,x3,y3,e:longint;
s:extended; function gcd(x,y:longint):longint;
begin
if y= then exit(x) else
exit(gcd(y,x mod y));
end; function calc_area(x1,y1,x2,y2,x3,y3:longint):extended;
begin
exit(abs((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1))/);
end; function solve(x1,y1,x2,y2:longint):longint;
begin
exit(gcd(abs(x1-x2),abs(y1-y2))+);
end; begin
//assign(input,'poj2954.in');reset(input);
//assign(output,'a.out');rewrite(output);
while not eof do
begin
readln(x1,y1,x2,y2,x3,y3);
if (x1=)and(y1=)and(x2=)and(y2=)and(x3=)and(y3=) then halt;
s:=calc_area(x1,y1,x2,y2,x3,y3);
e:=solve(x1,y1,x2,y2)+solve(x1,y1,x3,y3)+solve(x2,y2,x3,y3)-;
writeln(trunc(s-e/+));
end;
end.

POJ1265

 program poj1265;
const maxn=;
type point=record x,y:longint;end;
var t,test,n,e,i,tx,ty:longint;
s:extended;
a:array[-..maxn]of point; function gcd(x,y:longint):longint;
begin
if y= then exit(x) else
exit(gcd(y,x mod y));
end; function cross(p0,p1,p2:point):double;
begin
exit((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
end; begin
//assign(input,'poj1265.in');reset(input);
readln(test);
for t:= to test do
begin
readln(n);
a[].x:=;a[].y:=;
for i:= to n do
begin
readln(tx,ty);
a[i].x:=a[i-].x+tx;
a[i].y:=a[i-].y+ty;
end;
e:=;
for i:= to n- do inc(e,gcd(abs(a[i].x-a[i+].x),abs(a[i].y-a[i+].y)));
s:=;
for i:= to n do s:=s+cross(a[],a[i-],a[i])/;
s:=abs(s);
writeln('Scenario #',t,':');
writeln(trunc(s+-e/),' ',e,' ',s::);
writeln;
end;
end.
05-19 00:55