【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,一经查实,立即删除!

相关文章

java处理linux中的 m_Linux下处理BOM头和^M的简单方法

Linux在网络服务器、嵌入式设备的市场上占有较大份额&#xff0c;Microsoft Windows在桌面操作系统上占有较大的份额&#xff0c;因此有很多的人喜欢用Windows去控制操作Linux。既然用Windows去控制Linux&#xff0c;难免导致Windows系统上的产生的文件以某种途径传到了Linux系…

【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…

【FZU - 1759】Super A^B mod C (数论,快速幂,快速乘,欧拉降幂,指数循环节,模板)

题干&#xff1a; Given A,B,C, You should quickly calculate the result of A^B mod C. (1<A,C<1000000000,1<B<10^1000000). Input There are multiply testcases. Each testcase, there is one line contains three integers A, B and C, separated by a si…

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…

【AtCoder - 4242 】To Infinity(思维)

题干&#xff1a; Problem Statement Mr. Infinity has a string S consisting of digits from 1 to 9. Each time the date changes, this string changes as follows: Each occurrence of 2 in S is replaced with 22. Similarly, each 3 becomes 333, 4becomes 4444, 5 b…

java面向对象编程集合边框_JAVA 面向对象 集合框架

1.Java集合框架提供了一套性能优良、使用方便的接口和类&#xff0c;它们位于java.util包中如果并不知道程序运行时会需要多少对象&#xff0c;或者需要 更复杂方式存储对象——可以使用Java集合框架2.java集合框架包括接口、具体类、算法接口&#xff1a;Collection&#xff1…

【HDU - 2072 】单词数(字符串读入技巧,sstream大法,水题,字符串读入格式)

题干&#xff1a; lily的好朋友xiaoou333最近很空&#xff0c;他想了一件没有什么意义的事情&#xff0c;就是统计一篇文章里不同单词的总数。下面你的任务是帮助xiaoou333解决这个问题。 Input 有多组数据&#xff0c;每组一行&#xff0c;每组就是一篇小文章。每篇小文章都…

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

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

【HDU - 1251 】统计难题(字典树,求拥有公共前缀的字符串数量)

题干&#xff1a; Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是…

java 轮询请求接口_js调用轮询接口

##### 项目中遇到需要很多个需要轮询处理的接口&#xff0c;然后简单的封装了下&#xff0c;做个记录&#xff0c;以后用到类似的直接copy #####// polling-utils.js/*** descripting 轮询功能* param {String} type 请求类型* param {String} url 地址* param {Object} data 请…

【POJ - 2001 】Shortest Prefixes (字典树,查询重复前缀区间)

题干&#xff1a; A prefix of a string is a substring starting at the beginning of the given string. The prefixes of "carbon" are: "c", "ca", "car", "carb", "carbo", and "carbon". Note t…

mysql use index用法_MySQL中USE INDEX 和 FORCE INDEX

问题在一次生产环境排查性能问题时, 发现有个请求在一些用户的数据量比较大的情况下, 最高耗时差不多要3s. 而且还是一个轮询的请求.原因在排查问题时, 定位到是执行某条SQL时在用户的数据比较大的情况下, SQL执行耗时要1.5s.mysql> SELECT count(1)-> FROM-> cc_sess…

【AtCoder - 4244 】AtCoder Express 2 (区间dp 或 暴力枚举,思维)

题干&#xff1a; In Takahashi Kingdom, there is a east-west railroad and N cities along it, numbered 1, 2, 3, ..., N from west to east. A company called AtCoder Express possesses Mtrains, and the train i runs from City Li to City Ri (it is possible that L…

【HDU - 3068】最长回文(Manacher算法,马拉车算法求最长回文子串)

题干&#xff1a; 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S 两组case之间由空行隔开(该空行不用…

java程序员面试需要英语吗_Java程序员和高级程序员面试30题(英语)

Java程序员和高级程序员面试30题(英语)* Q1. How could Java classes direct program messages to the system console, but error messages, say to a file?A. The class System has a variable out that represents the standard output, and the variable err that represe…

【HDU - 1867 】A + B for you again(KMP,next数组应用)

题干&#xff1a; Generally speaking, there are a lot of problems about strings processing. Now you encounter another such problem. If you get two strings, such as “asdf” and “sdfg”, the result of the addition between them is “asdfg”, for “sdf” is …

wifisetting.java_Wifi 笔记 | 启动流程

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

【CodeForces - 589F】Gourmet and Banquet (贪心,思维,二分)

题干&#xff1a; A gourmet came into the banquet hall, where the cooks suggested n dishes for guests. The gourmet knows the schedule: when each of the dishes will be served. For i-th of the dishes he knows two integer moments in time ai and bi (in second…

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…