【POJ - 1556】The Doors (计算几何,线段相交)

题干:

You are to find the length of the shortest path through a chamber containing obstructing walls. The chamber will always have sides at x = 0, x = 10, y = 0, and y = 10. The initial and final points of the path are always (0, 5) and (10, 5). There will also be from 0 to 18 vertical walls inside the chamber, each with two doorways. The figure below illustrates such a chamber and also shows the path of minimal length. 

Input

The input data for the illustrated chamber would appear as follows. 


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

The output should contain one line of output for each chamber. The line should contain the minimal path length rounded to two decimal places past the decimal point, and always showing the two decimal places past the decimal point. The line should contain no blanks.

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

题目大意:

房间里有n堵墙,每面墙上有两扇门,求从房间最左端中点到最右端中点的最短路径 

解题报告:

把起点,终点,每个墙上的4个点分别看成图的顶点,这样一共就是4*n+2个点,我们把起点和终点当做第4*n+1和4*n+2这两个点,其余的每四个点为一组读数,读完顺便加边。

然后就是把这个点和之前所有读过的点连成一条边(假设共能连cnt条边),然后每条边依次连好的边(也就是墙)判断是否相交,如果和所有的墙都不相交,那么就加边(到dis数组中),然后跑floyd最短路就可以了。

写代码能力还是挫啊、、搞了一小时、、

 

AC代码:

#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdio>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const double eps = 1e-8;
int sgn(double x) {if(fabs(x) < eps)return 0;if(x < 0) return -1;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;}
} p[1005];
struct Line {Point s,e;Line() {}Line(Point s,Point e):s(s),e(e) {}pair<Point,int> operator &(const Line &b)const {Point res = s;if(sgn((s-e)^(b.s-b.e)) == 0) {if(sgn((b.s-s)^(b.e-s)) == 0)return make_pair(res,0);//两直线重合else return make_pair(res,1);//两直线平行}double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));res.x += (e.x - s.x)*t;res.y += (e.y - s.y)*t;return make_pair(res,2);//有交点,并返回交点}
} line[1005];
inline double xmult(Point p0,Point p1,Point p2) { return (p1-p0)^(p2-p0);}//p0p1 X p0p2
bool Seg_inter_line(Line l1,Line l2) { return sgn(xmult(l2.s,l1.s,l1.e))*sgn(xmult(l2.e,l1.s,l1.e)) <= 0;}//判断直线l1和线段l2是否相交
double dist(Point a,Point b) {return sqrt((b - a)*(b - a));}
bool inter(Line l1,Line l2) {//判断线段相交returnmax(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))<=0&&sgn((l1.s-l2.s)^(l2.e-l2.s))*sgn((l1.e-l2.s)^(l2.e-l2.s))<=0;
}
//两线段相交判断
//2 规范相交
//1 非规范相交
//0 不相交
int segcrossseg(Line l1,Line l2) {int d1 = sgn((l1.e-l1.s)^(l2.s-l1.s));int d2 = sgn((l1.e-l1.s)^(l2.e-l1.s));int d3 = sgn((l2.e-l2.s)^(l1.s-l2.s));int d4 = sgn((l2.e-l2.s)^(l1.e-l2.s));if( (d1^d2)==-2 && (d3^d4)==-2 )return 2;return (d1==0 && sgn((l2.s-l1.s)*(l2.s-l1.e))<=0) ||(d2==0 && sgn((l2.e-l1.s)*(l2.e-l1.e))<=0) ||(d3==0 && sgn((l1.s-l2.s)*(l1.s-l2.e))<=0) ||(d4==0 && sgn((l1.e-l2.s)*(l1.e-l2.e))<=0);
}
//直线和线段相交判断
//-*this line -v seg
//2 规范相交
//1 非规范相交
//0 不相交
int linecrossseg(Line l1,Line l2) {//l1直线,l2线段 int d1 = sgn((l1.e-l1.s)^(l2.s-l1.s));int d2 = sgn((l1.e-l1.s)^(l2.e-l1.s));if((d1^d2)==-2) return 2;return (d1==0||d2==0);
}
int totP,totL;
int n;
double dis[1005][1005];
void add(int num) {int up = num%4==0 ?  num-4 : num-(num%4);//最多跑到哪个点 for(int i = 1; i<=up; i++) {int flag = 1;for(int j = 1; j<=totL; j++) {if(segcrossseg(Line(p[num],p[i]),line[j]) == 2) {flag=0;break;}}if(flag) {dis[i][num] = dis[num][i] = dist(p[i],p[num]);}}//与起点 int flag = 1;for(int j = 1; j<=totL; j++) {if(segcrossseg(Line(p[num],p[4*n+1]),line[j]) == 2) {flag=0;break;}}if(flag) {dis[4*n+1][num] = dis[num][4*n+1] = dist(p[4*n+1],p[num]);}
}
int main()
{double y1,y2,y3,y4,x;while(~scanf("%d",&n)) {if(n == -1) break;//共4*n+1个顶点totP = 0;//因为起点 站了一个了 (还是起点单独算吧、、、) totL = 0;p[4*n+1] = Point(0,5);p[4*n+2] = Point(10,5);for(int i = 1; i<=4*n+10; i++) {for(int j = 1; j<=4*n+10; j++) {dis[i][j] = 1000000000;}}for(int i = 1; i<=n; i++) {scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4);p[++totP] = Point(x,y1);line[++totL] = Line(Point(x,0),p[totP]);p[++totP] = Point(x,y2);p[++totP] = Point(x,y3);line[++totL] = Line(p[totP-1],p[totP]);p[++totP] = Point(x,y4);line[++totL] = Line(p[totP],Point(x,10));add(totP);add(totP-1);add(totP-2);add(totP-3);}add(4*n+2);
//		dis[totP][4*n+2] = dis[4*n+2][totP] = dist(Point(totP),Point(p[4*n+2]));
//		dis[totP-1][4*n+2] = dis[4*n+2][totP] = dist(Point(totP),Point(p[4*n+2]));
//		dis[totP][4*n+2] = dis[4*n+2][totP] = dist(Point(totP),Point(p[4*n+2]));
//		dis[totP][4*n+2] = dis[4*n+2][totP] = dist(Point(totP),Point(p[4*n+2]));for(int k = 1; k<=totP+2; k++) {for(int i = 1; i<=totP+2; i++) {for(int j = 1; j<=totP+2; j++) {if(dis[i][k] + dis[k][j] < dis[i][j]) {dis[i][j] = dis[i][k] + dis[k][j];}}}}printf("%.2f\n",dis[4*n+1][4*n+2]);}	
}
/*
1
7 3 4.5 6 7*/ 

总结:

  说一下选定思路后开始敲代码的历程,首先模板没的说,然后开始想读入点的时候,用构造函数构造点,构造边,是都需要记录下来呢还是可以只构造点,然后遍历的时候再   每两个点连成一条边    来进行判断,后来发现这样不太好,也不太适合。因为你这样会把  -每条墙的边和矩形的边框的边的交点-  那个点,也算在判断的范围中了,但是我们是不需要这个点的,也就是说不需要判断这个点和其他点之间的关系,所以我们考虑也把每一条可以用到的边都记录下来,然后一边读入一边存点存边并且构图(最短路的图),刚开始想把起点存成id=1,终点存成id=4*n+2,但是发现这样不太好,因为这样就打乱了四条边一组的这一不错的关系,因为用这一关系(因为可以取模了啊 毕竟可以分组),我们可以用一个处理就得出了我们需要判断的up的值,(如果不是这种存id的方法的话,那就是2,3,4,5是一组,6,7,8,9是一组,这样就得写一堆if else、、)然后写add函数,刚开始直接up=num-(num%4),后来发现第一个样例都跑不出来,找bug,找到,改。这也是一个小trick啊以后别再犯了、、、找到这个bug的同时发现我没有让他和起点去连线(因为他的坐标是4*n+1啊所以肯定没有被比较过)所以我们需要单独让他俩连线跑一次。

   然后第二个样例没过去,检查后发现是最短路中应该是totP+2,我忘了+2了。。

   然后 dis数组初始化,本来想memset,,一想不对啊这是double类型,不能memset了,,然后最后写了四行想让终点和最后一个墙中的点都建图,但是一想这样写不好,因为可能他和其他前面的墙也可以建图呢。。所以直接add一下得了。。于是乎代码出来了。。。然后一发AC、、

坑点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/441366.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【POJ - 1696】Space Ant (凸包,最小极角,排序)

题干&#xff1a; The most exciting space discovery occurred at the end of the 20th century. In 1999, scientists traced down an ant-like creature in the planet Y1999 and called it M11. It has only one eye on the left side of its head and just three feet al…

2019蓝桥杯Java决赛题答案_2019第十届蓝桥杯JavaB组省赛真题详解

目录题解待更新第一题&#xff1a;组队题目描述做为篮球队教练&#xff0c;你须要从如下名单中选出 1 号位至 5 号位各一名球员&#xff0c; 组成球队的首发阵容。每位球员担任 1 号位至 5 号位时的评分以下表所示。请你计算首发阵容 1 号位至 5 号位的评分之和最大多是多少&am…

java map统计学生名单_Java含自己的总结:集合,学生,遍历,ArrayList,Set,Map,泛型,班级,发牌—诗书画唱...

声明一个ArrayList&#xff0c;存储一条学生信息&#xff0c;内容为 1 张三 22 男&#xff0c;将信息进行遍历出来package list;import java.util.ArrayList;import java.util.Iterator;public class student{public static void main(String[] args) {ArrayList jiHe…

java生成world文件_HelloWorld.java文件如何创建?

原创HelloWorld.java文件如何创建&#xff1f;编辑:小丸子 来源:PC下载网时间:2017-10-17 19:55:54相信各位刚接触JAVA的新人都希望尽快编写出自己的第一个程序,今天PC下载网小编和你一起学习HelloWorld程序1.首先我们先点击“开始”—然后是“所有程序”—在然后是“附件”—记…

wifisetting.java_Wifi 笔记 | 启动流程

csd&#xff1a;csdn_of_coder/article/details/51541094aosp: Android OAndroid网络各个模式中&#xff0c;Wifi应该是目前最常用的一种网络方式了&#xff1b;下面就简单介绍下Android中Wifi的启动流程。当我在Setting菜单里点击打开Wifi时&#xff0c;调用的入口函数是WifiM…

java 调用动态链接库_JAVA技巧:JNative调用动态链接库问题(SOS)

动态链接库的方法如下&#xff1a;__declspec(dllexport) ret __stdcall rLachTran(const char *pc_trancode,const char *pc_clicode,const char *pc_orgcode,const char *pc_ttycode,const int i_brandid,const char *pc_reqstamp,const int i_reqseqno,const char *pc_svrip…

【POJ - 3347 】Kadj Squares (计算几何,思维 或 扫描线)

题干&#xff1a; In this problem, you are given a sequence S1, S2, ..., Sn of squares of different sizes. The sides of the squares are integer numbers. We locate the squares on the positive x-y quarter of the plane, such that their sides make 45 degrees w…

按钮开关java代码,Android自定义实现开关按钮代码

我们在应用中经常看到一些选择开关状态的配置文件&#xff0c;做项目的时候用的是android的Switch控件&#xff0c;但是感觉好丑的样子子个人认为还是自定义的比较好&#xff0c;先上个效果图&#xff1a;实现过程&#xff1a;1.准备开关不同状态的两张图片放入drawable中。2.x…

*【CodeForces - 202C 】Clear Symmetry (思维,找规律,特判)

题干&#xff1a; Consider some square matrix A with side n consisting of zeros and ones. There are nrows numbered from 1 to n from top to bottom and n columns numbered from 1 to n from left to right in this matrix. Well denote the element of the matrix wh…

*【CodeForces - 768B】Code For 1 (分治策略,模拟二分思想,模拟线段树思想)

题干&#xff1a; Jon fought bravely to rescue the wildlings who were attacked by the white-walkers at Hardhome. On his arrival, Sam tells him that he wants to go to Oldtown to train at the Citadel to become a maester, so he can return and take the decease…

matlab 自适应噪声对消,基于Matlab的RLS自适应语音噪声对消系统的设计与实现

基于Matlab 的R LS 自适应语音噪声对消系统的设计与实现①肖 哲(湖南工业大学科技学院, 湖南株洲 412008)摘 要:自适应信号处理的理论和技术经过40多年的发展和完善,已逐渐成为人们常用的语音去噪技术.而Matlab 的出现又为其提供了更为方便快捷的方法来对语音信号进行消噪处…

贪心算法 -- 最小延迟调度

转自&#xff1a;https://blog.csdn.net/bqw18744018044/article/details/80285414 总结&#xff1a; 首先&#xff0c;证明贪心的时候交换论证是万能的&#xff01;其次&#xff0c;这一点如果要满足&#xff0c;也就是&#xff0c;如果你要用交换论证法&#xff0c;那么首先…

apache2+支持php7,Ubuntu14.04下配置PHP7.0+Apache2+Mysql5.7

Apache步骤一&#xff1a;安装apacheronyaoubuntu:~$ sudo apt install apache2安装好后&#xff0c;在浏览器上输入localhost(服务器端&#xff0c;请输入你的IP地址)&#xff0c;回车就会看到&#xff1a;PHP7.0步骤二&#xff1a;Ubuntu14.04下的默认源是PHP5.0&#xff0c;…

【CodeForces - 1051D】Bicolorings (dp,类似状压dp)

题干&#xff1a; You are given a grid, consisting of 22 rows and nn columns. Each cell of this grid should be colored either black or white. Two cells are considered neighbours if they have a common border and share the same color. Two cells AA and BB be…

【 HDU - 1796】How many integers can you find (容斥原理,二进制枚举或者dfs)

题干&#xff1a; Now you get a number N, and a M-integers set, you should find out how many integers which are small than N, that they can divided exactly by any integers in the set. For example, N12, and M-integer set is {2,3}, so there is another set {2,…

【CodeForces - 1027B 】Numbers on the Chessboard (没有营养的找规律题,无聊题)

题干&#xff1a; You are given a chessboard of size nnnn. It is filled with numbers from 11 to n2n2 in the following way: the first ⌈n22⌉⌈n22⌉ numbers from 11 to ⌈n22⌉⌈n22⌉ are written in the cells with even sum of coordinates from left to right f…

【CodeForces - 1060C】Maximum Subrectangle (思维,预处理前缀和,dp,枚举长度)

题干&#xff1a; You are given two arrays aa and bb of positive integers, with length nn and mmrespectively. Let cc be an nmnm matrix, where ci,jai⋅bjci,jai⋅bj. You need to find a subrectangle of the matrix cc such that the sum of its elements is at m…

【Codeforces 631C 】Report(单调栈,思维模拟)

题干&#xff1a; Each month Blake gets the report containing main economic indicators of the company "Blake Technologies". There are n commodities produced by the company. For each of them there is exactly one integer in the final report, that d…

【CodeForces - 215A】Bicycle Chain (水题)

题干&#xff1a; Vasyas bicycle chain drive consists of two parts: n stars are attached to the pedal axle, m stars are attached to the rear wheel axle. The chain helps to rotate the rear wheel by transmitting the pedal rotation. We know that the i-th sta…

ubuntu 在线安装php,ubuntu在线安装LNMP

一直以来个人安装lamp环境都是源码编译的&#xff0c;这个过程呢其实也要去经历的&#xff0c;但是毕竟占用时间久&#xff0c;有些时候在做一些测试环境的时候&#xff0c;可以在线安装比较快源码编译nginx可看往期&#xff1a;Nginx的安装对于lnmp的在线安装&#xff0c;如下…