网格点围成一个多边形,顶点都在格点上,求多边形内部格点数,边上格点数和面积。
运用叉积求有向面积加起来得到面积,最大公约数得到边上格点数,再根据pick定理(S=a+b/2-1)计算内部格点数。注意输出最好用"%f"不要用"%lf"。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
#include <stack>
using namespace std;
const int mod=1e9+7;
#define type double
#define Vector Point
const double PI = 3.14159265358979323;
int Abs(int x){
if(x<0)return -x;
return x;
}
int gcd(int a,int b){
if(b==0)return a;
return gcd(b,a%b);
}
struct Point{
type x,y;
Point(){
}
Point(int x,int y):x(x),y(y){
}
Point operator-(Point other){
return Point(x-other.x,y-other.y);
}
};
//向量点积
type Dot(Vector a,Vector b){
return a.x*b.x + a.y*b.y;
}
//向量叉积
type Cross(Vector a,Vector b){
return a.x*b.y - a.y*b.x;
}
//向量长度
double Length(Vector a){
return sqrt(a.x*a.x+a.y*a.y+0.0);
}
//两向量夹角
type Angle(Vector a,Vector b){
return acos(Dot(a,b) / (Length(a)*Length(b))+0.0);
}
type Area(Point* pts,int sz){
type re=0;
for(int i=0;i<sz;i++){
re+=Cross(pts[i+1],pts[i]);
//cout<<"re="<<re<<endl;
}
re/=2.0;
if(re<0)re=-re;
return re;
}
Point pts[1010];
bool cmp(const Point& a,const Point& b){
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
int main(){
int t;
cin>>t;
int cas=0;
while(t--){
cas++;
int n; cin>>n;
pts[0].x=pts[0].y=0;
int onEdge=0;
for(int i=1;i<=n;i++){
int dx,dy;
cin>>dx>>dy;
onEdge+=gcd(Abs(dx),Abs(dy));
pts[i].x=pts[i-1].x+dx;
pts[i].y=pts[i-1].y+dy;
}
pts[n+1].x=pts[n+1].y=0;
double ans = Area(pts,n);
int inside=ans+1-onEdge/2;
printf("Scenario #%d:\n",cas);
printf("%d %d %.1f\n\n",inside,onEdge,ans);
}
return 0;
}