A 来,求个三角形面积玩玩。
利用叉乘的特性就直接得到三角形的面积,如果三点共线则三点不构成三角形。此时叉乘结果为0.

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const double eps = 1e-8;
int sgn(double x){if(fabs(x)<eps)return 0;if(x<0)return -1;else return 1;
}
struct Point {double x,y;Point(){};Point(double _x,double _y){x=_x,y=_y;}void input(){scanf("%lf%lf",&x,&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;}
};
int main()
{Point a,b,c;a.input();b.input();c.input();Point ab,cb;ab=Point(a-b);cb=Point(c-b);if(sgn(ab^cb)==0){printf("You're so funny\n");}else {printf("%.2lf\n",fabs(ab^cb)/2);}
}

B 我的玩具在哪里
这道题主要是判断点和线段的位置关系,根据每个点和每条线段的位置关系来判断这个点 在哪个位置里。

//点和直线的位置关系
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const double eps = 1e-8;
const double pi = acos(-1.0);
const double inf = 1e20;
const int maxn = 5e3+10;
int sgn(double x){if(fabs(x)<0)return 0;if(x<0)return -1;else return 1;
}
struct Point {double x,y;Point(){};Point (double _x,double _y){x=_x;y=_y;}void input(){scanf("%lf%lf",&x,&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;}
};
struct Line{Point s,e;int relation(Point p){int c=sgn((p-s)^(p-e));if(c<0)return 1;else if(c>0)return 2;else return 3;}
};
Line l[maxn];
Point p[maxn];
int sum[maxn];
int main()
{int n,m;double x1,y1,x2,y2;int cnt=0;memset(sum,0,sizeof(sum));scanf("%d%d%lf%lf%lf%lf",&n,&m,&x1,&y1,&x2,&y2);for(int i=0;i<n;i++){double u,v;scanf("%lf%lf",&u,&v);l[i].s=Point(u,y1);l[i].e=Point(v,y2);}for(int i=0;i<m;i++){double x,y;scanf("%lf%lf",&x,&y);p[i]=Point(x,y);}for(int i=0;i<m;i++){for(int j=0;j<n;j++){if(l[j].relation(p[i])==1){sum[j]++;continue;}}}cnt=sum[0];for(int i=1;i<n;i++){cnt+=(sum[i]-sum[i-1]);//cout<<cnt<<endl;}//cout<<m<<" "<<cnt<<endl;sum[n]=m-cnt;for(int i=0;i<=n;i++){if(i>0&&i<n)printf("%d: %d\n",i,sum[i]-sum[i-1]);else printf("%d: %d\n",i,sum[i]);}return 0;
}

C 板子练习
上课讲的板子往上堆就可以啦。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
using namespace std;
const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int maxn = 1010;
int sgn(double x){if(fabs(x)<eps)return 0;if(x<0)return -1;else return 1;
}
struct Point {double x,y;Point (){};Point (double _x,double _y){x=_x;y=_y;}void input(){scanf("%lf%lf",&x,&y);}bool operator < (Point b)const{return sgn(x-b.x)==0?sgn(y-b.y)<0:x<b.x;}bool operator == (Point b)const{return sgn(x-b.x)==0&&sgn(y-b.y)==0;}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);}Point operator / (const double &b)const{return Point (x/b,y/b);}Point operator * (const double &b)const{return Point (x*b,y*b);}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;}double len(){return hypot(x,y);}double len2(){return x*x+y*y;}Point trunc(double r){double l=len();if(!sgn(l))return *this;r/=l;return Point(x*r,y*r);}Point rotleft(){return Point(-y,x);}Point rotright(){return Point(y,-x);}double distance (Point p){return hypot(x-p.x,y-p.y);}
};
struct Line{Point s,e;Line(){};Line(Point _s,Point _e){s=_s;e=_e;}void input(){s.input();e.input();}double legth(){return s.distance (e);}double angle(){double k=atan2(e.y-s.y,e.x-s.x);if(sgn(k)<0)k+=pi;if(sgn(k-pi)==0)k-=pi;return k;}Point cross_point(Line v){double a1 = (v.e-v.s)^(s-v.s);double a2 = (v.e-v.s)^(e-v.s);return Point ((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));}double dis_point_to_line(Point p){return fabs((p-s)^(e-s))/legth();}double dis_point_to_seg(Point p){if(sgn((p-s)*(e-s))<0||sgn((p-e)*(s-e))<0)return min(p.distance(s),p.distance(e));return dis_point_to_line(p);}//返回点p在直线上的投影Point line_prog(Point p){return s+(((e-s)*((e-s)*(p-s)))/((e-s).len2()));}bool parallel (Line v){return sgn((e-s)^(v.e-v.s))==0;}
};
struct circle{Point p;double r;circle(){};circle(Point _p,double _r){p=_p;r=_r;}circle(double x,double y,double _r){p=Point(x,y);r=_r;}//三角形的外接圆circle(Point a,Point b,Point c){Line u = Line((a+b)/2,((a+b)/2)+((b-a).rotleft()));Line v = Line((b+c)/2,((b+c)/2)+((c-b).rotleft()));p = u.cross_point(v);r = p.distance(a);}//三角形内切圆circle(Point a,Point b,Point c,bool t){Line u,v;double m = atan2(b.y-a.y,b.x-a.x), n = atan2(c.y-a.y,c.x-a.x);u.s=a;u.e=u.s+Point(cos((n+m)/2),sin((n+m)/2));v.s=b;m=atan2(a.y-b.y,a.x-b.x), n= atan2(c.y-b.y,c.x-b.x);v.e = v.s+Point(cos((n+m)/2),sin((n+m)/2));p = u.cross_point(v);r = Line(a,b).dis_point_to_seg(p);}void input(){p.input();scanf("%lf",&r);}int relation_point(Point b){double dist = b.distance(p);if(sgn(dist - r)<0)return 2;else if(sgn(dist - r)==0) return 1;return 0;}//求直线和圆的交点int relation_line(Line v){double dist = v.dis_point_to_line(p);if(sgn(dist-r)<0)return 2;else if(sgn(dist-r)==0) return 1;return 0;}int relation_circle(circle v){double d = p.distance(v.p);if(sgn(d-r-v.r)>0)return 5;if(sgn(d-r-v.r)==0)return 4;double l =fabs(r-v.r);if(sgn(d-r-v.r)<0&&sgn(d-l)>0)return 3;if(sgn(d-l)==0)return 2;if(sgn(d-l)<0)return 1;}int point_cross_line(Line v,Point &p1,Point &p2){if(!(*this).relation_line(v))return 0;Point a = v.line_prog(p);double d = v.dis_point_to_line(p);d = sqrt(r*r-d*d);if(sgn(d)==0){p1=a;p2=a;return 1;}p1 = a+(v.e-v.s).trunc(d);p2 = a-(v.e-v.s).trunc(d);return 2;}int point_cross_circle(circle v,Point &p1,Point &p2){int rel = relation_circle(v);if(rel==1||rel==5)return 0;double d = p.distance(v.p);double l = (d*d+r*r-v.r*v.r)/(2*d);double h = sqrt(r*r-l*l);Point temp = p+(v.p-p).trunc(l);p1=temp + ((v.p-p).rotleft().trunc(h));p2=temp + ((v.p-p).rotright().trunc(h));if(rel == 2||rel ==4){return 1;}return 2;}int tangent_line(Point q,Line &u,Line &v){int x = relation_point(q);if(x==2) return 0;if(x==1){u=Line(q,q+(q-p).rotleft());v=u;return 1;}double d=p.distance (q);double l=r*r/d;double h=sqrt(r*r-l*l);u=Line(q,p+((q-p).trunc(l)+(q-p).rotleft().trunc(h)));v=Line(q,p+((q-p).trunc(l)+(q-p).rotright().trunc(h)));return 2;}//得过与直线u相切,过点q,半径为r1的圆int get_circle(Line u,Point q,double r1,circle &c1,circle &c2){double dis=u.dis_point_to_line(q);if(sgn(dis-r1*2)>0)return 0;if(sgn(dis)==0){c1.p=q+((u.e-u.s).rotleft().trunc(r1));c2.p=q+((u.e-u.s).rotright().trunc(r1));c1.r=c2.r=r1;return 2;}Line u1=Line((u.s+(u.e-u.s).rotleft().trunc(r1)),(u.e+(u.e-u.s).rotleft().trunc(r1)));Line u2=Line((u.s+(u.e-u.s).rotright().trunc(r1)),(u.e+(u.e-u.s).rotright().trunc(r1)));circle cc=circle(q,r1);Point p1,p2;if(!cc.point_cross_line(u1,p1,p2))cc.point_cross_line(u2,p1,p2);c1=circle(p1,r1);if(p1==p2){c2=c1;return 1;}c2=circle(p2,r1);return 2;}//同时与直线u,v相切,半径为r1的圆;int get_circle(Line u,Line v,double r1,circle &c1,circle &c2,circle &c3,circle &c4){if(u.parallel(v))return 0;Line u1=Line(u.s+(u.e-u.s).rotleft().trunc(r1),u.e+(u.e-u.s).rotleft().trunc(r1));Line u2=Line(u.s+(u.e-u.s).rotright().trunc(r1),u.e+(u.e-u.s).rotright().trunc(r1));Line v1=Line(v.s+(v.e-v.s).rotleft().trunc(r1),v.e+(v.e-v.s).rotleft().trunc(r1));Line v2=Line(v.s+(v.e-v.s).rotright().trunc(r1),v.e+(v.e-v.s).rotright().trunc(r1));c1.r=c2.r=c3.r=c4.r=r1;c1.p=u1.cross_point(v1);c2.p=u1.cross_point(v2);c3.p=u2.cross_point(v1);c4.p=u2.cross_point(v2);return 4;}//同时与不相交的两个圆cx,cy相切  ,半径为r1的圆int get_circle(circle cx,circle cy,double r1,circle &c1,circle &c2){circle x(cx.p,r1+cx.r),y(cy.p,r1+cy.r);int t=x.point_cross_circle(y,c1.p,c2.p);if(!t)return 0;c1.r=c2.r=r1;return t;}
};
int main()
{string s;while(cin>>s){if(s=="CircumscribedCircle"){Point a1,a2,a3;a1.input();a2.input();a3.input();circle ans(a1,a2,a3);printf("(%.6lf,%.6lf,%.6lf)\n",ans.p.x,ans.p.y,ans.r);}if(s=="InscribedCircle"){Point a1,a2,a3;a1.input();a2.input();a3.input();circle ans(a1,a2,a3,true);printf("(%.6lf,%.6lf,%.6lf)\n",ans.p.x,ans.p.y,ans.r);}if(s=="TangentLineThroughPoint"){circle c;c.input();Point pp;pp.input();Line uu,vv;int ans=c.tangent_line(pp,uu,vv);if(ans==0)printf("[]\n");if(ans==1)printf("[%.6lf]\n",uu.angle()/pi*180.0);if(ans==2){double res[5];res[0]=uu.angle();res[1]=vv.angle();sort(res,res+2);printf("[%.6lf,%.6lf]\n",res[0]/pi*180.0,res[1]/pi*180.0);}}if(s=="CircleThroughAPointAndTangentToALineWithRadius"){Point pp;pp.input();Line uu;uu.input();double rr;scanf("%lf",&rr);circle c,c1,c2;int ans=c.get_circle(uu,pp,rr,c1,c2);if(ans==0)printf("[]\n");if(ans==1)printf("[(%.6lf,%.6lf)]\n",c1.p.x,c1.p.y);if(ans==2){Point yx[5];yx[0]=c1.p;yx[1]=c2.p;sort(yx,yx+2);printf("[(%.6lf,%.6lf),(%.6lf,%.6lf)]\n",yx[0].x,yx[0].y,yx[1].x,yx[1].y);}}if(s=="CircleTangentToTwoLinesWithRadius"){Line u,v;double r1;circle c,c1,c2,c3,c4;u.input();v.input();scanf("%lf",&r1);c.get_circle(u,v,r1,c1,c2,c3,c4);Point yx[5];yx[0]=c1.p;yx[1]=c2.p;yx[2]=c3.p;yx[3]=c4.p;sort(yx,yx+4);printf("[(%.6lf,%.6lf),(%.6lf,%.6lf),(%.6lf,%.6lf),(%.6lf,%.6lf)]\n",yx[0].x,yx[0].y,yx[1].x,yx[1].y,yx[2].x,yx[2].y,yx[3].x,yx[3].y);}if(s=="CircleTangentToTwoDisjointCirclesWithRadius"){circle c,cx,cy,c1,c2;cx.input();cy.input();double r1;scanf("%lf",&r1);int ans=c.get_circle(cx,cy,r1,c1,c2);if(ans==0)printf("[]\n");if(ans==1)printf("[(%.6lf,%.6lf)]\n",c1.p.x,c1.p.y);if(ans==2){Point yx[5];yx[0]=c1.p;yx[1]=c2.p;sort(yx,yx+2);printf("[(%.6lf,%.6lf),(%.6lf,%.6lf)]\n",yx[0].x,yx[0].y,yx[1].x,yx[1].y);}}}
}

D 沙漠骆驼
这是一道判断线段相交和最短路的结合问题。
把每扇门(就是危险地带可以走的地方)看作是两个点然后利用计算几何的知识来判断一下两个点所形成的线段与图中的墙(也就是线段)有没有相交,规范相交与重合才算相交,对于不相交的两个点之间建立边,然后跑最短路就可以了。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const double eps = 1e-8;
const double pi = acos(-1.0);
const double inf = 1e20;
const int maxn = 1010;
int sgn(double x){if(fabs(x)<0)return 0;if(x<0)return -1;else return 1;
}
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;}double distance (Point b){return hypot(x-b.x,y-b.y);}
};
//两点距离
double dist(Point a,Point b)
{return sqrt((b-a)*(b-a));
}
struct Line{Point s,e;Line(){};Line(Point _s,Point _e){s=_s;e=_e;}Line(double x1,double y1,double x2,double y2){s.x=x1;s.y=y1;e.x=x2;e.y=y2;}//线段与线段相交判断//2 规范相交//1 非规范相交//0 不相交int seg_cross_seg(Line v){int d1 = sgn((e-s)^(v.s-s));int d2 = sgn((e-s)^(v.e-s));int d3 = sgn((v.e-v.s)^(s-v.s));int d4 = sgn((v.e-v.s)^(e-v.s));if((d1^d2)==-2&&(d3^d4)==-2) return 2;return (d1==0 &&sgn((v.s-s)*(v.s-e))<=0)||(d2==0 &&sgn((v.e-s)*(v.e-e))<=0)||(d3==0 &&sgn((s-v.s)*(s-v.e))<=0)||(d4==0 &&sgn((e-v.s)*(e-v.e))<=0);}int relation(Point p){int c=sgn((p-s)^(p-e));if(c<0)return 1;else if(c>0) return 2;else return 3;}bool parallel(Line v){return sgn((e-s)^(v.e-v.s))==0;}//直线与直线相交判断//0 平行//1 重合//2 相交int line_cross_line(Line v){if((*this).parallel(v))return v.relation(s)==3;return 2;}
};
struct edge{int ss,ee;double w;int next;
};
struct qnode{double dist;int num;bool operator < (const qnode &b)const{return dist>b.dist;}
};
edge e[maxn*maxn];
double dis[maxn];
int vis[maxn];
Point p[maxn];
Line s[maxn];
int head[maxn];
int cnt;
void add_edge(int ss,int ee,double ww){e[++cnt].ss=ss;e[cnt].ee=ee;e[cnt].w=ww;e[cnt].next=head[ss];head[ss]=cnt;
}
double dijkstra(int ss,int ee){priority_queue<qnode>q;qnode now,temp;dis[ss]=0;vis[ss]=1;now.dist=dis[ss];now.num=ss;q.push(now);while(!q.empty()){now=q.top();q.pop();vis[now.num]=0;for(int i=head[now.num];i!=-1;i=e[i].next){if(dis[e[i].ee]>now.dist+e[i].w){dis[e[i].ee]=now.dist+e[i].w;if(!vis[e[i].ee]){temp.dist=dis[e[i].ee];temp.num=e[i].ee;q.push(temp);vis[e[i].ee]=1;}}}}return dis[ee];
}
int main(){int n;scanf("%d",&n);cnt=0;fill(dis,dis+maxn,inf);memset(head,-1,sizeof(head));memset(vis,0,sizeof(vis));int p_cnt=0,s_cnt=0;for(int i=0;i<n;i++){double x,y[4];scanf("%lf%lf%lf%lf%lf",&x,&y[0],&y[1],&y[2],&y[3]);for(int j=0;j<4;j++){p[p_cnt++]=Point(x,y[j]);}s[s_cnt++]=Line(x,0,x,y[0]);s[s_cnt++]=Line(x,y[1],x,y[2]);s[s_cnt++]=Line(x,y[3],x,10.0);}p[p_cnt++]=Point (10.0,5.0);p[p_cnt++]=Point (0.0,5.0);for(int i=0;i<p_cnt;i++){for(int j=0;j<p_cnt;j++){Line temp=Line(p[i],p[j]);int flag=0;for(int k=0;k<s_cnt;k++){if(temp.seg_cross_seg(s[k])==2){// 规范相交flag=1;break;}if(temp.seg_cross_seg(s[k])==1){ //非规范相交要判断是否重合if(temp.line_cross_line(s[k])==1){//如成立 说明重合flag=1;break;}}}//cout<<i<<" "<<j<<" "<<flag<<" "<<g<<endl;if(!flag){add_edge(i,j,dist(p[i],p[j]));//cout<<e[cnt].ss<<" "<<e[cnt].ee<<" "<<e[cnt].w<<endl;add_edge(j,i,dist(p[i],p[j]));//cout<<e[cnt].ss<<" "<<e[cnt].ee<<" "<<e[cnt].w<<endl;}}}double ans = dijkstra(p_cnt-2,p_cnt-1);printf("%.2f\n",ans);return 0;
}

2019 SUST暑期集训题解(计算几何(平面几何))相关推荐

  1. 2019 SUST暑期集训题解(计算几何(二))

    A . 梦想成为天文学家 这道题是一个原题,我们要用向量的知识来解决它,求解的就是四点共面. //四个点三个向量 构成一个行列式 行列式的结果为0则共面否则不共面 #include<iostre ...

  2. SUST暑期集训题解(可持久化数据结构)

    A 可持久化线段树 #include<iostream> #include<cstdio> #include<cstring> #include<algori ...

  3. 2019年暑期集训总结

    2019年的暑期集训结束了,时间是2019/07/18--2019/08/23,这也是我参加的第二次暑假集训了吧,一个多月的时间,学到了很多,也收获了很多,不仅仅是学习,关系也近了很多,也成长了很多. ...

  4. SUST 2019暑期集训题解(差分约束+生成树+传递闭包)

    A 这个不等式组很眼熟吧 这道题的话上课讲过就是根据不等式建图然后跑一下最短路就可以了. #include<iostream> #include<cstring> #inclu ...

  5. 题解报告(CDUT暑期集训——第五场)

    题解报告(CDUT暑期集训--第五场) B - Beautiful Now HDU - 6351 思路:直接暴力全排列就行了 最多\(10!\)次 题目限制2500ms 全排列大概是2000多ms(最 ...

  6. 题解报告(CDUT暑期集训——第三场)

    题解报告(CDUT暑期集训--第三场) A - Problem A. Ascending Rating HDU - 6319 思路:单调队列板子题?(但是弱的一批的我还是不会用(有空补上 用的滑动窗口 ...

  7. 题解报告(CDUT暑期集训——第二场)

    题解报告(CDUT暑期集训--第二场) D - Game HDU - 6312 思路:水题 Alice一直是必胜态 AC代码 #include<stdio.h> #include<i ...

  8. 题解报告(CDUT暑期集训——第四场)

    题解报告(CDUT暑期集训--第四场) Problem D. Nothing is Impossible HDU - 6335 思路:水题 排个序循环判断就出来了 AC代码 #include<s ...

  9. 题解报告(CDUT暑期集训——第一场)

    题解报告(CDUT暑期集训--第一场) A - Maximum Multiple HDU - 6298 思路:先按照题意打表 发现规律 就出来了(最开始没开long long贡献了3发 然后又忘了换行 ...

最新文章

  1. 12C expdp issue
  2. MQ 消息中间件梳理
  3. (一)ubuntu 12.04 安装php5.5
  4. 微信小程序 openid及支付的若干问题解决方案
  5. 算法时间复杂度分析基础
  6. archer mysql源码_自动化运维工具inception+archer
  7. Atitit. 高级软件工程师and 普通的区别 高级编程的门槛总结
  8. 针对CDP协议攻击分析及安全防护
  9. rsync定时任务引起cpu负载高
  10. java ldap操作实例_Java Spring Security示例教程中的2种设置LDAP Active Directory身份验证的方法...
  11. 遍历二叉树的全部方法(递归+非递归)
  12. VMware虚拟机安装Linux系统(详解版)
  13. oracle清除bin,Oracle recyclebin详解(闪回删除的表)
  14. django源码阅读
  15. scrum 11.28
  16. 【图像融合】基于matlab CBF算法图像融合【含Matlab源码 083期】
  17. 微信小程序源代码demo
  18. 优秀的求职者,是如何巧妙应对面试提问呢?
  19. movmedian函数matlab,MEDIAN函数用法及实例
  20. 【放马过来---谈禅修打坐】

热门文章

  1. Intel原厂固态SSD硬盘抢先评测
  2. matlab 通讯系统设计与仿真,基于BPSK通信系统的设计与仿真
  3. 雨落竹轩(来自好友)
  4. Python入门总结-默单词程序
  5. buildroot编译和使用
  6. python的内置字典数据类型_python 数据类型元组与字典内置方法
  7. Lifecycle的基本使用和原理
  8. Macbook 开发之器,Mac OSX 应用软件,开发工具必备网站推荐
  9. 盖茨18年首富成就福布斯神话 揭示盖茨不为人知的秘密
  10. PostgreSQL 多维空间几何对象 相交、包含 高效率检索实践 - cube