1.poj2318 TOYS

传送:http://poj.org/problem?id=2318

题意:有m个点落在n+1个区域内。问落在每个区域的个数。

分析:二分查找落在哪个区域内。叉积判断点与线段的位置。

 #include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
struct point{
int x,y;
point(){ }
point(int _x,int _y):x(_x),y(_y){}
point operator +(const point &b) const{
return point(x+b.x,y+b.y);
}
point operator -(const point &b) const{
return point(x-b.x,y-b.y);
}
int operator *(const point &b) const{
return x*b.x,y*b.y;
}
int operator ^(const point &b) const{
return x*b.y-y*b.x;
}
};
struct line{
point s,e;
line(){}
line(point _s,point _e):s(_s),e(_e){}
}box[maxn];
int xmult(point p,point a,point b){
return (b-a)^(p-a);
}
int ans[maxn];
int main(){
ios::sync_with_stdio(false);
cin.tie();cout.tie();
int n,m,x1,y1,x2,y2,ui,li,x,y;
int _=;
while (cin >> n >> m >> x1 >> y1 >> x2 >> y2 && n){
if (_!=) cout << endl;
for (int i=;i<n;i++){
cin >> ui >> li;
box[i]=line(point(ui,y1),point(li,y2));
}
box[n]=line(point(x2,y1),point(x2,y2));
memset(ans,,sizeof(ans));
point p;
for (int i=;i<m;i++){
cin >> x >> y;
p=point(x,y);
int l=,r=n,mid,tmp;
while (l<=r){
mid=(l+r)>>;
if (xmult(p,box[mid].s,box[mid].e)<){
tmp=mid;
r=mid-;
}
else l=mid+;
}
ans[tmp]++;
}
for (int i=;i<=n;i++) cout << i << ": " << ans[i] << endl;
_++;
}
return ;
}

poj2318

2.poj2398 Toy Storage

传送:http://poj.org/problem?id=2398

题意:与poj2318相同,输出要求输出有t(t>0)个玩具的格子数。

分析:同2318

 #include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
struct point{
int x,y;
point(){ }
point(int _x,int _y):x(_x),y(_y){}
point operator +(const point &b) const{
return point(x+b.x,y+b.y);
}
point operator -(const point &b) const{
return point(x-b.x,y-b.y);
}
int operator *(const point &b) const{
return x*b.x,y*b.y;
}
int operator ^(const point &b) const{
return x*b.y-y*b.x;
}
};
struct line{
point s,e;
line(){}
line(point _s,point _e):s(_s),e(_e){}
//
bool operator< (const line &b) const{
return s.x<b.s.x;
} }box[maxn];
int cmp(line p,line q){
return p.s.x<q.s.x;
}
int xmult(point p,point a,point b){
return (a-p)^(b-p);
}
int ans[maxn],vis[maxn];
int main(){
ios::sync_with_stdio(false);
cin.tie();cout.tie();
int n,m,x1,y1,x2,y2,ui,li,x,y;
while (cin >> n >> m >> x1 >> y1 >> x2 >> y2 && n){
for (int i=;i<n;i++){
cin >> ui >> li;
box[i]=line(point(ui,y1),point(li,y2));
}
box[n]=line(point(x2,y1),point(x2,y2));
sort(box,box++n);
memset(ans,,sizeof(ans));
point p;
for (int i=;i<m;i++){
cin >> x >> y;
p=point(x,y);
int l=,r=n,mid,tmp;
while (l<=r){
mid=(l+r)>>;
if (xmult(p,box[mid].s,box[mid].e)<){
tmp=mid;
r=mid-;
}
else l=mid+;
}
ans[tmp]++;
}
memset(vis,,sizeof(vis));
for (int i=;i<=n;i++) if (ans[i]) vis[ans[i]]++;
cout << "Box\n";
for (int i=;i<=n;i++){
if (!vis[i]) continue;
cout << i << ": " << vis[i] << endl;
}
}
return ;
}

poj2398

3.poj3304 Segments

传送:http://poj.org/problem?id=3304

题意:给出n条线段两个端点的坐标,问所有线段投影到一条直线上,如果这些所有投影至少相交于一点就输出Yes!,否则输出No!。

分析:如果有存在这样的直线,过投影相交区域作直线的垂线,该垂线必定与每条线段相交,问题转化为问是否存在一条线和所有线段相交。

直线肯定经过两个端点。两两枚举端点(包括同一条线段),判断直线和线段是否相交。

 #include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps=1e-;
const int maxn=;
struct point{
double x,y;
point(){}
point(double _x,double _y):x(_x),y(_y){}
point operator -(const point &b) const{
return point(x-b.x,y-b.y);
}
double operator ^(const point &b) const{
return x*b.y-y*b.x;
}
double operator *(const point &b) const{
return x*b.x+y*b.y;
}
};
struct line{
point s,t;
line(){}
line(point _s,point _t):s(_s),t(_t){}
}a[maxn];
int sgn(double x){
if (fabs(x)<eps) return ;
if (x<) return -;
return ;
}
double xmult(point p,point a,point b){ // PA X PB
return (a-p)^(b-p);
}
int seg_inter_line(line l1,line l2){
return sgn(xmult(l2.s,l1.s,l1.t))*sgn(xmult(l2.t,l1.s,l1.t))<=;
}
double dist(point a,point b){
return sqrt((b-a)*(b-a));
}
int check(line l1,int n){
if (sgn(dist(l1.s,l1.t))==) return ;
for (int i=;i<n;i++)
if (seg_inter_line(l1,a[i])==) return ;
return ;
}
int main(){
int t,n; cin >> t;
double x1,x2,y1,y2;
while (t--){
cin >> n;
for (int i=;i<n;i++){
cin >> x1 >> y1 >> x2 >> y2;
a[i]=line(point(x1,y1),point(x2,y2));
}
int f=;
for (int i=;i<n;i++){
for (int j=;j<n;j++){
if (check(line(a[i].s,a[j].s),n) || check(line(a[i].s,a[j].t),n)
|| check(line(a[i].t,a[j].s),n) || check(line(a[i].t,a[j].t),n)){
f=; break;
}
}
}
if (f) cout << "Yes!\n";
else cout << "No!\n";
}
}

poj3304

4.poj1269 Intersecting Lines

传送:http://poj.org/problem?id=1269

题意:给出两条直线,问两条直线的位置关系(平行,重合,相交)。相交的话输出交点。

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const double eps=1e-;
int sgn(double x){
if (fabs(x)<eps) return ;
if (x<) return -;
return ;
}
struct point{
double x,y;
point(){}
point(double _x,double _y):x(_x),y(_y){}
point operator -(const point &b) const{
return point(x-b.x,y-b.y);
}
double operator ^(const point &b) const{
return x*b.y-y*b.x;
}
double operator *(const point &b) const{
return x*b.x+y*b.y;
}
};
struct line{
point s,t;
line(){}
line(point _s,point _t):s(_s),t(_t){}
pair<point,int> operator &(const line &b) const{
point res=s;
if (sgn((s-t)^(b.s-b.t))==){
if (sgn((b.s-s)^(b.t-s))==) return make_pair(res,); //两直线重合
else return make_pair(res,); //两直线平行
}
double k=((s-b.s)^(b.s-b.t))/((s-t)^(b.s-b.t));
res.x+=(t.x-s.x)*k;
res.y+=(t.y-s.y)*k;
return make_pair(res,); //两直线相交
}
};
int main(){
int n; cin >> n;
double x1,x2,y1,y2;
line l1,l2;
cout << "INTERSECTING LINES OUTPUT\n";
for (int i=;i<n;i++){
cin >> x1 >> y1 >> x2 >> y2;
l1=line(point(x1,y1),point(x2,y2));
cin >> x1 >> y1 >> x2 >> y2;
l2=line(point(x1,y1),point(x2,y2));
pair<point,int> ans=l1&l2;
if (ans.second==) printf("POINT %.2f %.2f\n",ans.first.x,ans.first.y);
else if (ans.second==) printf("NONE\n");
else printf("LINE\n");
}
cout << "END OF OUTPUT\n";
return ;
}

poj1269

5.poj1556 The Doors

传送:http://poj.org/problem?id=1556

题意:10×10的方阵内有若干个墙壁,墙壁之间有空隙(可通过),问从(0,5)到(10,5)的最短路。

分析:建图,线段两两判断是否相交,不相交就建边。然后跑最短路。(数据较小,随便最短路算法。

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<algorithm>
using namespace std;
const double eps=1e-;
const double inf=1e20;
const int maxn=;
double mp[maxn][maxn];
int sgn(double x){
if (fabs(x)<eps) return ;
if (x<) return -;
return ;
}
struct point{
double x,y;
point(){}
point(double _x,double _y):x(_x),y(_y){}
point operator -(const point &b) const{
return point(x-b.x,y-b.y);
}
double operator ^(const point &b) const{
return x*b.y-y*b.x;
}
double operator *(const point &b) const{
return x*b.x+y*b.y;
}
};
struct line{
point s,e;
line(){}
line(point _s,point _e):s(_s),e(_e){}
}a[maxn];
double dist(point a,point b){
return sqrt((b-a)*(b-a));
}
int inter(line l1,line l2){
return
max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x)
&& max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x)
&& max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y)
&& max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y)
&& sgn((l2.s-l1.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s))<=
&& sgn((l1.s-l2.s)^(l2.e-l2.s))*sgn((l1.e-l2.s)^(l2.e-l2.s))<=;
}
double floyd(int n){
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
for (int k=;k<=n;k++)
if (mp[i][k]+mp[k][j]<mp[i][j]) mp[i][j]=mp[i][k]+mp[k][j];
return mp[][n];
}
int main(){
int n; double x,y1,y2,y3,y4;
while (cin >> n && n!=-){
for (int i=;i<=n;i++){
cin >> x >> y1 >> y2 >> y3 >> y4;
a[*i-]=line(point(x,y1),point(x,y2));
a[*i]=line(point(x,y3),point(x,y4));
}
for (int i=;i<=*n+;i++)
for (int j=;j<=*n+;j++)
if (i==j) mp[i][j]=;else mp[i][j]=inf;
for (int i=;i<=*n;i++){
int l=(i+)/;
int f=;
point tmp;
if (i&) tmp=a[(i+)/].s; else tmp=a[(i+)/].e;
for (int j=;j<l;j++)
if (inter(a[*j-],line(point(,),tmp))==
&& inter(a[*j],line(point(,),tmp))==) f=;
if (f) mp[][i]=mp[i][]=dist(point(,),tmp);
f=;
for (int j=l+;j<=n;j++)
if (inter(a[*j-],line(point(,),tmp))==
&& inter(a[*j],line(point(,),tmp))==) f=;
if (f) mp[i][*n+]=mp[*n+][i]=dist(point(,),tmp);
}
for (int i=;i<=*n;i++){
for (int j=i+;j<=*n;j++){
int l1=(i+)/,l2=(j+)/;
int f=;
point p1,p2;
if (i&) p1=a[(i+)/].s; else p1=a[(i+)/].e;
if (j&) p2=a[(j+)/].s; else p2=a[(j+)/].e;
for (int k=l1+;k<l2;k++)
if (inter(a[*k-],line(p1,p2))==
&& inter(a[*k],line(p1,p2))==) f=;
if (f) mp[i][j]=mp[j][i]=dist(p1,p2);
}
}
int f=;
for (int i=;i<=n;i++)
if (inter(a[*i-],line(point(,),point(,)))==
&& inter(a[*i],line(point(,),point(,)))==) f=;
if (f) mp[][*n+]=mp[*n+][]=;
double ans=floyd(*n+);
printf("%.2f\n",ans);
}
return ;
}

poj1556

6.poj2653 Pick-up sticks

传送:http://poj.org/problem?id=2653

题意:问有多少线段不与比它编号大的相交。

分析:线段交直接暴力判断。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const double eps=1e-;
const int maxn=;
int sgn(double x){
if (fabs(x)<eps) return ;
if (x<) return -;
return ;
}
struct point{
double x,y;
point(){}
point(double _x,double _y):x(_x),y(_y){}
point operator -(const point &b) const{
return point(x-b.x,y-b.y);
}
double operator ^(const point &b) const{
return x*b.y-y*b.x;
}
double operator *(const point &b) const{
return x*b.x+y*b.y;
}
};
struct line{
point s,e;
line(){}
line(point _s,point _e):s(_s),e(_e){}
}a[maxn];
double dist(point a,point b){
return sqrt((b-a)*(b-a));
}
int inter(line l1,line l2){
return
max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x)
&& max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x)
&& max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y)
&& max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y)
&& sgn((l2.s-l1.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s))<=
&& sgn((l1.s-l2.s)^(l2.e-l2.s))*sgn((l1.e-l2.s)^(l2.e-l2.s))<=;
}
bool vis[maxn];
int main(){
ios::sync_with_stdio(false);
cin.tie();cout.tie();
int n; double x1,x2,y1,y2;
while (cin >> n && n){
for (int i=;i<n;i++){
cin >> x1 >> y1 >> x2 >> y2;
a[i]=line(point(x1,y1),point(x2,y2));
vis[i]=;
}
for (int i=;i<n;i++){
for (int j=i+;j<n;j++){
if (inter(a[i],a[j])){vis[i]=;break;}
}
}
cout << "Top sticks: ";
int f=;
for (int i=;i<n;i++){
if (!vis[i]) continue;
if (f){cout << i+;f=;}
else cout << ", " << i+;
}
cout << ".\n";
}
}

poj2653

7.poj1066 Treasure Hunt

传送:http://poj.org/problem?id=1066

题意:在金字塔内有一个宝藏p(x,y);现在要取出这个宝藏在金字塔内有许多墙为了进入宝藏所在的房间必须把墙炸开但是炸墙只能炸每个房间墙的中点求将宝藏运出城堡所需要的最小炸墙数。

分析:枚举每个线段的端点与P点形成的直线,与多少线段相交。其次,可以从墙壁顶点进入,相交数+1与ans比较。
 #include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const double dx[]={,,,},dy[]={,,,};
const double eps=1e-;
const int maxn=;
int sgn(double x){
if (fabs(x)<eps) return ;
if (x<) return -;
return ;
}
struct point{
double x,y;
point(){}
point(double _x,double _y):x(_x),y(_y){}
point operator -(const point &b) const{
return point(x-b.x,y-b.y);
}
double operator ^(const point &b) const{
return x*b.y-y*b.x;
}
double operator *(const point &b) const{
return x*b.x+y*b.y;
}
}p[*maxn];
struct line{
point s,e;
line(){}
line(point _s,point _e):s(_s),e(_e){}
}a[maxn];
int inter(line l1,line l2){
return
max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x)
&& max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x)
&& max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y)
&& max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y)
&& sgn((l2.s-l1.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s))<=
&& sgn((l1.s-l2.s)^(l2.e-l2.s))*sgn((l1.e-l2.s)^(l2.e-l2.s))<=;
}
int main(){
int n; double x1,y1,x2,y2;
while (cin >> n){
for (int i=;i<=n;i++){
cin >> x1 >> y1 >> x2 >> y2;
a[i]=line(point(x1,y1),point(x2,y2));
p[*i-]=point(x1,y1); p[*i]=point(x2,y2);
}
point s;
cin >> x1 >> y1;
s=point(x1,y1);
int ans=;
for (int i=;i<=*n;i++){
line l1=line(s,p[i]);
int res=;
for (int j=;j<=n;j++)
if (inter(l1,a[j])) res++;
ans=min(res,ans);
}
for (int i=;i<;i++){
line l1=line(s,point(dx[i],dy[i]));
int res=;
for (int j=;j<=n;j++)
if (inter(l1,a[j])) res++;
ans=min(ans,res+);
}
cout << "Number of doors = " << ans << endl;
}
return ;
}

poj1066

8.poj1410 Intersection

传送:http://poj.org/problem?id=1410

题意:给定一个矩阵和线段,若线段在矩阵内或与矩阵某条边相交,输出T,否则输出F。

分析:判断线段与四条边线段交。再判断是否在矩阵内。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const double eps=1e-;
const int maxn=;
int sgn(double x){
if (fabs(x)<eps) return ;
if (x<) return -;
return ;
}
struct point{
double x,y;
point(){}
point(double _x,double _y):x(_x),y(_y){}
point operator -(const point &b) const{
return point(x-b.x,y-b.y);
}
double operator ^(const point &b) const{
return x*b.y-y*b.x;
}
double operator *(const point &b) const{
return x*b.x+y*b.y;
}
}p[maxn];
struct line{
point s,e;
line(){}
line(point _s,point _e):s(_s),e(_e){}
};
int inter(line l1,line l2){
return
max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x)
&& max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x)
&& max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y)
&& max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y)
&& sgn((l2.s-l1.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s))<=
&& sgn((l1.s-l2.s)^(l2.e-l2.s))*sgn((l1.e-l2.s)^(l2.e-l2.s))<=;
}
int onseg(point p,line l){
return
sgn((l.s-p)^(l.e-p))== &&
sgn((p.x-l.s.x)*(p.x-l.e.x))<= &&
sgn((p.y-l.s.y)*(p.y-l.e.y))<=;
}
//判断点在凸多边形内
//点形成一个凸包,而且按逆时针排序(如果是顺时针把里面的<0改为>0)
//点的编号:0~n-1
//返回值:
//-1:点在凸多边形外
//0:点在凸多边形边界上
//1:点在凸多边形内
int inConvexPoly(point a,point p[],int n){
for (int i=;i<n;i++){
if (sgn((p[i]-a)^(p[(i+)%n]-a))<) return -;
else if (onseg(a,line(p[i],p[(i+)%n]))) return ;
}
return ;
}
int main(){
int t; cin >> t;
double x1,y1,x2,y2;
while (t--){
cin >> x1 >> y1 >> x2 >> y2;
line l=line(point (x1,y1),point(x2,y2));
cin >> x1 >> y1 >> x2 >> y2;
if (x1>x2) swap(x1,x2); if (y1>y2) swap(y1,y2);
p[]=point(x1,y1);p[]=point(x2,y1);p[]=point(x2,y2);p[]=point(x1,y2);
if (inter(l,line(p[],p[])) || inter(l,line(p[],p[]))
|| inter(l,line(p[],p[])) || inter(l,line(p[],p[]))){
cout << "T\n";continue;
}
if (inConvexPoly(l.s,p,)>= || inConvexPoly(l.e,p,)>=){
cout << "T\n"; continue;
}
cout << "F\n";
}
return ;
}

poj1410

9.poj1696 Space Ant

传送:http://poj.org/problem?id=1696

题意:一只蚂蚁只会向左转,现在给出平面上很多个点,求解一种走法能使得蚂蚁能经过的点最多,每个顶点该蚂蚁只能经过一次,且所行走的路线不能发生交叉。

分析:对于题目所输入的点,先找出最左下方的顶点(即纵坐标最小的顶点),然后对剩下的顶点按照对与左下点的极角排序,然后反复找最左下的点,反复进行极角排序,同时记录排序后左下的顶点。

极角排序方法:利用叉积,看向量p1和p2的叉积是否小于零,是则说明p1在p2逆时针方向,即p1的极角比p2的大,极角相同则按离p0距离降序排序。

 #include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const double eps=1e-;
const int maxn=;
int sgn(double x){
if (fabs(x)<eps) return ;
if (x<) return -;
return ;
}
struct point{
double x,y;
int id;
point(){}
point(double _x,double _y):x(_x),y(_y){}
point operator -(const point &b) const{
return point(x-b.x,y-b.y);
}
double operator ^(const point &b) const{
return x*b.y-y*b.x;
}
double operator *(const point &b) const{
return x*b.x+y*b.y;
}
}p[maxn];
double dist(point a,point b){
return sqrt((a-b)*(a-b));
}
int pos;
int cmp(point a,point b){
double tmp=(a-p[pos])^(b-p[pos]);
if (sgn(tmp)==) return dist(a,p[pos])<dist(b,p[pos]);
else if (sgn(tmp)<) return false;
else return true;
}
int main(){
int t,n; cin >> t;
double x,y;
while (t--){
cin >> n;
for (int i=;i<n;i++){
cin >> p[i].id >> p[i].x >> p[i].y;
if (p[i].y<p[].y || p[i].y==p[].y && p[i].x<p[].x) swap(p[i],p[]);
}
pos=;
for (int i=;i<n;i++){
sort(p+i,p+n,cmp);
pos++;
}
cout << n;
for (int i=;i<n;i++) cout << " " << p[i].id;
cout << endl;
}
}

poj1696

10.poj3347 Kadj Squares

传送:http://poj.org/problem?id=3347

题意:给出n个边长的正方形,要求尽可能贴着放。问最后从上往下看能看到哪几个正方形。

分析:每新增一个正方形,就让他与左侧的每一个正方形贴紧,求的其左端坐标,最终结果一定是最大的那个。然后求的相应的最右端坐标。这样就转化为了线段,最后用朴素的n2算法求出每条线段没有被覆盖的长度,如果长度大于0,即可输出。

 #include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=;
struct node{
int len,l,r;
}a[maxn];
int main(){
int n;
while (cin >> n && n){
for (int i=;i<n;i++){
cin >> a[i].len; //将图形扩大根2倍,len为对角线长度的一半
a[i].l=;
for (int j=;j<i;j++){
a[i].l=max(a[i].l,a[j].r-abs(a[i].len-a[j].len));
}
a[i].r=a[i].l+*a[i].len;
}
for (int i=;i<n;i++){
for (int j=;j<i;j++){
if (a[i].l<a[i].r){
if (a[i].len<a[j].len && a[i].l<a[j].r) a[i].l=a[j].r;
else if (a[i].len>a[j].len && a[i].l<a[j].r) a[j].r=a[i].l;
}
}
}
for (int i=;i<n;i++){
if (a[i].l<a[i].r) cout << i+ << " ";
}
cout << endl;
}
return ;
}

poj3347

11.poj1654 Area

传送:http://poj.org/problem?id=1654

题意:从原点开始,超八个方向走。问最后形成的多边形面积。

分析:rt。直接求多边形面积。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int dx[]={,-,,,-,,,-,,},dy[]={,-,-,-,,,,,,};
const int maxn=;
typedef long long ll;
struct point{
int x,y;
point(){}
point(int _x,int _y):x(_x),y(_y){}
ll operator ^(const point &b)const{
return x*b.y-y*b.x;
}
};
struct polygon{
int n;
point p[maxn];
void add(point q){p[n++]=q;}
ll getarea(){
ll sum=;
for (int i=;i<n;i++) sum+=(p[i]^(p[(i+)%n]));
return sum<?-sum:sum;
}
};
polygon C;
int main(){
char ch;
int t,k; cin >> t;
while (t--){
C.n=;
ll x=,y=;
while (cin >> ch && ch!=''){
k=ch-'';
x+=dx[k]; y+=dy[k];
C.add(point(x,y));
}
ll ans=C.getarea();
if (ans&) cout << ans/ << ".5\n";
else cout << ans/ << endl;
}
return ;
}

poj1654

12.poj2954 Triangle

  传送:http://poj.org/problem?id=2954

  题意:求三角形内部有多少格点。

  分析:pick定理。S=a+b/2-1。a代表多边形内部的格点,b代表多边形边上的格点。S代表多边形面积。

  

 #include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=;
struct point{
int x,y;
point(){}
point(int _x,int _y):x(_x),y(_y){}
ll operator ^(const point &b)const{
return x*b.y-y*b.x;
}
};
struct polygon{
int n;
point p[maxn];
void add(point q){p[n++]=q;}
ll getarea(){
ll sum=;
for (int i=;i<n;i++) sum+=(p[i]^p[(i+)%n]);
return sum<?-sum:sum;
}
};
polygon C;
ll gcd(ll a,ll b){
if (b==) return a;
else return gcd(b,a%b);
}
int main(){
int x1,x2,x3,y1,y2,y3;
while (cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3){
if (!x1 && !x2 && !x3 && !y1 && !y2 && !y3) break;
C.n=;
C.add(point(x1,y1));C.add(point(x2,y2));C.add(point(x3,y3));
ll area=C.getarea();
int b=;
for (int i=;i<C.n;i++){
b+=gcd(abs(C.p[i].x-C.p[(i+)%C.n].x),abs(C.p[i].y-C.p[(i+)%C.n].y));
}
cout << (area+-b)/ << endl; //S=a+b/2-1
}
return ;
}

poj2954

【kuangbin专题】计算几何基础的更多相关文章

  1. [kuangbin]专题六 最小生成树 题解+总结

    kuangbin专题链接:https://vjudge.net/article/752 kuangbin专题十二 基础DP1 题解+总结:https://www.cnblogs.com/RioTian ...

  2. nyis oj 68 三点顺序 (计算几何基础)

    三点顺序 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描写叙述 如今给你不共线的三个点A,B,C的坐标,它们一定能组成一个三角形,如今让你推断A,B,C是顺时针给出的还是逆 ...

  3. kuangbin专题 数论基础 part1?

    线段树专题太难了,那我来做数学吧! 但数学太难了,我......(扯 这两天想了做了查了整理了几道数学. 除了一些进阶的知识,像莫比乌斯反演,杜教筛,min25学不会我跳了,一些基础的思维还是可以记录 ...

  4. 【BZOJ】1043: [HAOI2008]下落的圆盘(计算几何基础+贪心)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1043 唯一让我不会的就是怎么求圆的周长并QAAQ... 然后发现好神!我们可以将圆弧变成$[0, 2 ...

  5. 计算几何基础——矢量和叉积 && 叉积、线段相交判断、凸包(转载)

    转载自 http://blog.csdn.net/william001zs/article/details/6213485 矢量 如果一条线段的端点是有次序之分的话,那么这种线段就称为 有向线段,如果 ...

  6. BZOJ_1610_[Usaco2008_Feb]_Line连线游戏_(计算几何基础+暴力)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1610 给出n个点,问两两确定的直线中,斜率不同的共有多少条. 分析 暴力枚举直线,算出来斜率放 ...

  7. 二维计算几何基础题目泛做(SYX第一轮)

    题目1: POJ 2318 TOYS 题目大意: 给一个有n个挡板的盒子,从左到右空格编号为0...n.有好多玩具,问每个玩具在哪个空格里面. 算法讨论: 直接叉积判断就可以.注意在盒子的边界上面也算 ...

  8. 最小生成树 kuangbin专题最后一个题

    题目链接:https://cn.vjudge.net/contest/66965#problem/N 注释:这道题需要用krustra,用prim的话可能会超时.并且在计算距离的时候要尽量减少步骤,具 ...

  9. kuangbin专题十六 KMP&&扩展KMP HDU2087 剪花布条

    一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Input输入中含有一些数据,分别是成对出现的花布条和小 ...

随机推荐

  1. Django之url定义和ORM框架的使用

    前言,Django安装 pip install django # 官网安装最新版本 pip install django -i "https://pypi.doubanio.com/simp ...

  2. 58.UIScrollView XIB拖拽约束

    第一步: 拖拽UIScrollView 到控制器上 ,给scrollView 添加约束 ,这时是正常的 第二步:scrollview上添加UIview ,(注意:这个 ScrollView就是根据这个 ...

  3. Mysql命令drop database:删除数据库

    drop命令用于删除数据库. drop命令格式:drop database <数据库名>; 例如,删除名为 xhkdb的数据库:mysql> drop database xhkdb; ...

  4. tomcat7 安装 windows 服务

    tomcat 可以安装成windows 服务,这样 每次启动就不需要启动tomcat了. 具体配置: 1.修改 service.bat 在行首添加 set "JAVA_HOME=E:\jdk ...

  5. 大道至简第一章和java理论学时第一节。感受。

    这周上了本学期的第一节java课程.课件上说了一些学习java的基本思想.举了个“愚公移山”的例子.这可能就像刚接触一门新的语言,来练习输出“HelloWorld”一样,已成惯例. “愚公移山”的这个 ...

  6. Alpha阶段敏捷冲刺(五)

    1.站立式会议 提供当天站立式会议照片一张 2.每个人的工作 (有work item 的ID),并将其记录在码云项目管理中: 昨天已完成的工作. 祁泽文:实现了个人遗忘曲线图 徐璐琳:完成了微信Web ...

  7. 网络timeout区分

    ConnectTimeout 连接建立时间,三次握手完成时间 SocketTimeout 数据传输过程中数据包之间间隔的最大时间 下面重点说下SocketTimeout,比如有如下图所示的http请求 ...

  8. mysql同时使用order by和limit查询时的一个严重隐患 -- 丢失数据

    转自: https://blog.csdn.net/tsxw24/article/details/44994835 我经常使用order by和limit来做数据分页显示并排序,一直也没发现过什么问题 ...

  9. 初始Yarn

    YARN 产生背景 MapReduce1.x存在的问题:单点故障&节点压力大.不易扩展 资源利用率&运维成本 催生了YARN的诞生 YARN:不同计算框架可以共享同一个HDFS集群上的 ...

  10. Swift简单实现一个常规条款、免责声明文字+带有链接的展示形式

    效果:   IMG_F08DABE063A6-1.jpeg class DisclamerView: UIView { //@objc weak var vc:UIViewController? // ...