The Doors(几何+最短路,好题)
The Doors
http://poj.org/problem?id=1556
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 10466 | Accepted: 3891 |
Description

Input
2
4 2 7 8 9
7 3 4.5 6 7
The first line contains the number of interior walls. Then there is a line for each such wall, containing five real numbers. The first number is the x coordinate of the wall (0 < x < 10), and the remaining four are the y coordinates of the ends of the doorways in that wall. The x coordinates of the walls are in increasing order, and within each line the y coordinates are in increasing order. The input file will contain at least one such set of data. The end of the data comes when the number of walls is -1.
Output
Sample Input
- 1
- 5 4 6 7 8
- 2
- 4 2 7 8 9
- 7 3 4.5 6 7
- -1
Sample Output
- 10.00
- 10.06
Source
有18堵墙!!!因为没看清这个疯狂爆RE
poj上交C++会CE,要自己写hypot函数
- double hypot(double x,double y){
- return sqrt(x*x+y*y);
- }
- #include<cstdio>
- #include<iostream>
- #include<cstring>
- #include<cmath>
- #include<vector>
- #include<algorithm>
- using namespace std;
- const double eps=1e-;
- const double INF=1e20;
- const double PI=acos(-1.0);
- const int maxp=;
- int sgn(double x){
- if(fabs(x)<eps) return ;
- if(x<) return -;
- else return ;
- }
- inline double sqr(double x){return x*x;}
- struct Point{
- double x,y;
- Point(){}
- Point(double _x,double _y){
- x=_x;
- y=_y;
- }
- void input(){
- scanf("%lf %lf",&x,&y);
- }
- void output(){
- printf("%.2f %.2f\n",x,y);
- }
- bool operator == (const Point &b)const{
- return sgn(x-b.x) == && sgn(y-b.y)== ;
- }
- bool operator < (const Point &b)const{
- return sgn(x-b.x)==?sgn(y-b.y)<:x<b.x;
- }
- 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 len(){
- return hypot(x,y);
- }
- //返回长度的平方
- double len2(){
- return x*x+y*y;
- }
- //返回两点的距离
- double distance(Point p){
- return hypot(x-p.x,y-p.y);
- }
- Point operator + (const Point &b)const{
- return Point(x+b.x,y+b.y);
- }
- Point operator * (const double &k)const{
- return Point(x*k,y*k);
- }
- Point operator / (const double &k)const{
- return Point(x/k,y/k);
- }
- //计算pa和pb的夹角
- //就是求这个点看a,b所成的夹角
- ///LightOJ1202
- double rad(Point a,Point b){
- Point p=*this;
- return fabs(atan2(fabs((a-p)^(b-p)),(a-p)*(b-p)));
- }
- //化为长度为r的向量
- Point trunc(double r){
- double l=len();
- if(!sgn(l)) return *this;
- r/=l;
- return Point(x*r,y*r);
- }
- //逆时针转90度
- Point rotleft(){
- return Point(-y,x);
- }
- //顺时针转90度
- Point rotright(){
- return Point(y,-x);
- }
- //绕着p点逆时针旋转angle
- Point rotate(Point p,double angle){
- Point v=(*this) -p;
- double c=cos(angle),s=sin(angle);
- return Point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
- }
- };
- struct Line{
- Point s,e;
- Line(){}
- Line(Point _s,Point _e){
- s=_s;
- e=_e;
- }
- bool operator==(Line v){
- return (s==v.s)&&(e==v.e);
- }
- //根据一个点和倾斜角angle确定直线,0<=angle<pi
- Line(Point p,double angle){
- s=p;
- if(sgn(angle-PI/)==){
- e=(s+Point(,));
- }
- else{
- e=(s+Point(,tan(angle)));
- }
- }
- //ax+by+c=0;
- Line(double a,double b,double c){
- if(sgn(a)==){
- s=Point(,-c/b);
- e=Point(,-c/b);
- }
- else if(sgn(b)==){
- s=Point(-c/a,);
- e=Point(-c/a,);
- }
- else{
- s=Point(,-c/b);
- e=Point(,(-c-a)/b);
- }
- }
- void input(){
- s.input();
- e.input();
- }
- void adjust(){
- if(e<s) swap(s,e);
- }
- //求线段长度
- double length(){
- return s.distance(e);
- }
- //返回直线倾斜角 0<=angle<pi
- double angle(){
- double k=atan2(e.y-s.y,e.x-s.x);
- if(sgn(k)<) k+=PI;
- if(sgn(k-PI)==) k-=PI;
- return k;
- }
- //点和直线的关系
- //1 在左侧
- //2 在右侧
- //3 在直线上
- int relation(Point p){
- int c=sgn((p-s)^(e-s));
- if(c<) return ;
- else if(c>) return ;
- else return ;
- }
- //点在线段上的判断
- bool pointonseg(Point p){
- return sgn((p-s)^(e-s))==&&sgn((p-s)*(p-e))<=;
- }
- //两向量平行(对应直线平行或重合)
- bool parallel(Line v){
- return sgn((e-s)^(v.e-v.s))==;
- }
- //两线段相交判断
- //2 规范相交
- //1 非规范相交
- //0 不相交
- int segcrossseg(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)==-&&(d3^d4)==-) return ;
- return (d1==&&sgn((v.s-s)*(v.s-e))<=||
- d2==&&sgn((v.e-s)*(v.e-e))<=||
- d3==&&sgn((s-v.s)*(s-v.e))<=||
- d4==&&sgn((e-v.s)*(e-v.e))<=);
- }
- //直线和线段相交判断
- //-*this line -v seg
- //2 规范相交
- //1 非规范相交
- //0 不相交
- int linecrossseg(Line v){
- int d1=sgn((e-s)^(v.s-s));
- int d2=sgn((e-s)^(v.e-s));
- if((d1^d2)==-) return ;
- return (d1==||d2==);
- }
- //两直线关系
- //0 平行
- //1 重合
- //2 相交
- int linecrossline(Line v){
- if((*this).parallel(v))
- return v.relation(s)==;
- return ;
- }
- //求两直线的交点
- //要保证两直线不平行或重合
- Point crosspoint(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 dispointtoline(Point p){
- return fabs((p-s)^(e-s))/length();
- }
- //点到线段的距离
- double dispointtoseg(Point p){
- if(sgn((p-s)*(e-s))<||sgn((p-e)*(s-e))<)
- return min(p.distance(s),p.distance(e));
- return dispointtoline(p);
- }
- //返回线段到线段的距离
- //前提是两线段不相交,相交距离就是0了
- double dissegtoseg(Line v){
- return min(min(dispointtoseg(v.s),dispointtoseg(v.e)),min(v.dispointtoseg(s),v.dispointtoseg(e)));
- }
- //返回点P在直线上的投影
- Point lineprog(Point p){
- return s+(((e-s)*((e-s)*(p-s)))/((e-s).len2()));
- }
- //返回点P关于直线的对称点
- Point symmetrypoint(Point p){
- Point q=lineprog(p);
- return Point(*q.x-p.x,*q.y-p.y);
- }
- };
- Line L[];
- int n;
- bool Check(Line a,Line b){
- if(sgn((a.s-a.e)^(b.s-a.e))*sgn((a.s-a.e)^(b.e-a.e))>) return false;
- if(sgn((b.s-b.e)^(a.s-b.e))*sgn((b.s-b.e)^(a.e-b.e))>) return false;
- if(sgn(max(a.s.x,a.e.x)-min(b.s.x,b.e.x))>=&&sgn(max(b.s.x,b.e.x)-min(a.s.x,a.e.x))>=
- &&sgn(max(a.s.y,a.e.y)-min(b.s.y,b.e.y))>=&&sgn(max(b.s.y,b.e.y)-min(a.s.y,a.e.y))>=)
- return true;
- else return false;
- }
- double mp[][];
- int co;
- void panduan(Line a,int xx,int yy){
- if(a.s.y==||a.s.y==||a.e.y==||a.e.y==) return;
- for(int i=;i<co;i++){
- if(i!=(xx+)/&&i!=(yy+)/){
- if(Check(a,L[i])){
- return;
- }
- }
- }
- //cout<<xx<<" "<<yy<<" "<<a.length()<<endl;
- mp[xx][yy]=mp[yy][xx]=a.length();
- }
- int main(){
- while(~scanf("%d",&n)){
- if(n==-) break;
- double x,y1,y2,y3,y4;
- co=;
- for(int i=;i<;i++){
- for(int j=;j<;j++){
- mp[i][j]=INF;
- }
- }
- Point s,e;
- s.x=,s.y=;
- e.x=,e.y=;
- //起点为0,终点为co
- for(int i=;i<=n;i++){
- scanf("%lf %lf %lf %lf %lf",&x,&y1,&y2,&y3,&y4);
- L[co].s.x=x,L[co].s.y=,L[co].e.x=x,L[co++].e.y=y1;
- L[co].s.x=x,L[co].s.y=y2,L[co].e.x=x,L[co++].e.y=y3;
- L[co].s.x=x,L[co].s.y=y4,L[co].e.x=x,L[co++].e.y=;
- }
- Line tmp;
- int j;
- //不包括起点和终点的建图
- for(int i=;i<co;i++){
- for(int j=i+;j<co;j++){
- tmp.s=L[i].s,tmp.e=L[j].s;
- panduan(tmp,(i-)*+,(j-)*+);
- tmp.s=L[i].s,tmp.e=L[j].e;
- panduan(tmp,(i-)*+,(j-)*+);
- tmp.s=L[i].e,tmp.e=L[j].s;
- panduan(tmp,(i-)*+,(j-)*+);
- tmp.s=L[i].e,tmp.e=L[j].e;
- panduan(tmp,(i-)*+,(j-)*+);
- }
- }
- //加上起点和终点
- for(int i=;i<co;i++){
- tmp.s=s,tmp.e=L[i].s;
- panduan(tmp,,(i-)*+);
- tmp.s=s,tmp.e=L[i].e;
- panduan(tmp,,(i-)*+);
- tmp.s=e,tmp.e=L[i].s;
- panduan(tmp,(i-)*+,);
- tmp.s=e,tmp.e=L[i].e;
- panduan(tmp,(i-)*+,);
- }
- tmp.s=s,tmp.e=e;
- panduan(tmp,,);
- for(int k=;k<=;k++)
- for(int i=;i<=;i++)
- for(int j=;j<=;j++)
- if(mp[i][j]>mp[i][k]+mp[k][j]+eps)
- mp[i][j]=mp[i][k]+mp[k][j];
- printf("%.2f\n",mp[][]);
- }
- return ;
- }
The Doors(几何+最短路,好题)的更多相关文章
- poj1511/zoj2008 Invitation Cards(最短路模板题)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud Invitation Cards Time Limit: 5 Seconds ...
- HDU 5521.Meeting 最短路模板题
Meeting Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- hdu-3790最短路刷题
title: hdu-3790最短路刷题 date: 2018-10-20 14:50:31 tags: acm 刷题 categories: ACM-最短路 概述 一道最短路的水题,,,尽量不看以前 ...
- [poj2449]Remmarguts' Date(K短路模板题,A*算法)
解题关键:k短路模板题,A*算法解决. #include<cstdio> #include<cstring> #include<algorithm> #includ ...
- 牛客小白月赛6 I 公交线路 最短路 模板题
链接:https://www.nowcoder.com/acm/contest/136/I来源:牛客网 题目描述 P市有n个公交站,之间连接着m条道路.P市计划新开设一条公交线路,该线路从城市的东站( ...
- POJ 1556 The Doors --几何,最短路
题意: 给一个正方形,从左边界的中点走到右边界的中点,中间有一些墙,问最短的距离是多少. 解法: 将起点,终点和所有墙的接触到空地的点存下来,然后两两之间如果没有线段(墙)阻隔,就建边,最后跑一个最短 ...
- 2018.07.06 POJ1556 The Doors(最短路)
The Doors Time Limit: 1000MS Memory Limit: 10000K Description You are to find the length of the shor ...
- POJ 4046 Sightseeing 枚举+最短路 好题
有n个节点的m条无向边的图,节点编号为1~n 然后有点权和边权,给出q个询问,每一个询问给出2点u,v 输出u,v的最短距离 这里的最短距离规定为: u到v的路径的所有边权+u到v路径上最大的一个点权 ...
- POJ 1556 The Doors(计算几何+最短路)
这题就是,处理出没两个点.假设能够到达,就连一条边,推断可不能够到达,利用线段相交去推断就可以.最后求个最短路就可以 代码: #include <cstdio> #include < ...
随机推荐
- 超链接中 utm_source, utm_medium 等参数的含义是什么?
作者:张溪梦 Simon链接:https://www.zhihu.com/question/48724061/answer/122730629来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非 ...
- 捷通华声TTS在Aster+中的安装过程
1)挂载TTS光碟 2)安装如下5个rpm软件包 [asterisk@TTS78:/mnt]$ls *.rpmjTTS-5.0.1.0-3.i386.rpm VocLib_Xi ...
- sklearn.svm.SVC 参数说明
原文地址:sklearn.svm.SVC 参数说明 ============================== 资源: sklearn官网+DOC 库下载GitHub =============== ...
- windows挂载gluseter NFS卷
windows下挂载gluster提供的NFS卷 服务器端的配置: 首先配置好NFS共享,找一台linux试一下,确保挂载成功.linux客户端执行:mount.nfs 10.33.70.20:tes ...
- 现在的 Linux 内核和 Linux 2.6 的内核有多大区别?
作者:larmbr宇链接:https://www.zhihu.com/question/35484429/answer/62964898来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转 ...
- 网络文件系统与 Linux
网络文件系统 是文件系统之上的一个网络抽象,来允许远程客户端以与本地文件系统类似的方式,来通过网络进行访问.虽然 NFS 不是第一个此类系统,但是它已经发展并演变成 UNIX® 系统中最强大最广泛使用 ...
- 如何决定Web应用的线程池大小
线程池(Thread Pool)在Web应用中线程池的大小决定了在任何一个时间点应用可以处理请求的并发数.如果一个系统收到的请求数超过了线程池的大小,那么超出的请求要么进入等待队列要么被拒绝.请注意, ...
- 代码生成器 CodeSmith 的使用(四)
在上一篇的版本中,我们生成了数据库中的字段,使生成的属性更加简洁,可读性也提高了很多,但都是钍对一个数据库的单个表,如果要将数据库中的所有 的表都生成相应的类,表中的字段也都生成属性,运行一次就可以将 ...
- Python——连接操作数据库
1.安装MySQL驱动程序.下载自动安装包,双击安装即可,非常简单. 2.连接MySQL,下面是Python示例代码. import MySQLdbconn=MySQLdb.connect(host= ...
- MVC 4 Razor Design Sample Demo Project
This is a demo project in MCV 4 razor design which encompases the general design of MVC pattern. The ...