POJ 1556
来源:互联网 发布:如何判定网络是否稳定 编辑:程序博客网 时间:2024/06/06 01:56
题目链接:http://poj.org/problem?id=1556
————————————————————————————————————————————————————
题目简述:如图中所示,已知起点和终点,中间有墙挡住,问最短的路是多长
————————————————————————————————————————————————————
解题思路:看别人的解题报告是用图+dijkstra做的。我没有用图论的方法,直接做的。
我的思路是,读入各点,按顺序存进p数组(p是个结构体,其中用了重载),因为每个x坐标就对应着4个点,所以不需要做标记,有寻址公式就行。
然后将x的坐标按顺序存到xs数组中。然后开始对各个点,按顺序扫描,如果和起点之间无障碍物,则该点的len就是到起点的距离。如果有障碍物,就
从p[0]点开始一个一个的扫描,如果与p[j]点之间没有障碍物,则计算出到该点距离加上该点的len。想法是很裸的(这个词刚刚学会),而且话说其实
应该把起点也放入p 数组中,这样不需要分情况讨论了,代码会更加简洁,不修改了。
其中对于障碍物的判断方法,我是这样做的: 如果我们当前状态是i,待检测的点是j,我们可以用点斜式列出过点i和点j的方程。将i和j之间的墙们的横坐标带进
方程(xs就用上了,再加上一个寻址公式),求出一个纵坐标,再考查纵坐标是否在墙上,就可以了。思路挺简单,不过写起来有点麻烦,寻址公式要特别小心。
————————————————————————————————————————————————————
题目小结:
一开始没有ac,遇到的问题多由粗心所致:
1、bst求出来之后,忘记赋值给p[i].len ( = = 这么傻的问题都能犯啊)。。。。
2、寻址公式写错了个地方。
另外,在写重载的时候,一开始没有编译通过,问题如下:
3、重载时重载函数要与结构体名一致。
————————————————————————————————————————————————————
待解问题:
1、重载时需要加入一行 Line(){};
否则会报错 |error: no matching function for call to 'Line::Line()'|,不知为何
2、由于符号重载时多加了个 &,故报warning: reference to local variable 'c' returned|
下学期就该学c++,大概到时候就明白了吧,先搁着!
————————————————————————————————————————————————————
源代码,其中判断相交的函数没用上,算作下次的模板。
#include<cstdio>#include<cstring>#include<algorithm>#include<math.h>using namespace std;typedef float T;struct Pt{ T x; T y; T len; Pt(){} Pt(T px,T py) { x = px; y = py; } Pt &operator +(const Pt &p) const { Pt c; c.x = x + p.x; c.y = y + p.y; return c; } Pt &operator -(const Pt &p) const { Pt c; c.x = x - p.x; c.y = y - p.y; return c; }};struct Line{ Pt a; Pt b; int cont; Line(){} Line (Pt p1,Pt p2) { a = p1; b = p2; }}line[1010];T dpr(Pt a,Pt b,Pt c) //µã»ý{ return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y);}T cpr(Pt a,Pt b,Pt c) //ab * ac{ return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);}bool cmp(Line l1,Line l2){ return l1.a.x < l2.a.x;}T min(T a,T b){ if(a>b) return b; else return a;}bool segments_intersect(Pt p1,Pt p2,Pt p3,Pt p4) //严格相交,即交在端点不算相交,不需要判断交点位置,相交时返回1。本题亦不会出现点在线段上的问题{ float d1,d2,d3,d4; d1 = cpr(p1,p3,p4); d2 = cpr(p2,p3,p4); d3 = cpr(p3,p1,p2); d4 = cpr(p4,p1,p2); if(d1*d2<0 && d3*d4<0) return 1; else return 0;}Pt p[100],p0,pn;int k = 0,m = 0;float xs[100];bool segments(Pt a,Pt b,int i,int j) //求与各个x的交点{ int k = 0,t = 0; T y = 0; for(k = i/4+1;k<j/4+1;k++) { y = a.y + (b.y - a.y)*(xs[k] - a.x)/(b.x-a.x); if(y < p[(k-1)*4].y || (y<p[(k-1)*4+2].y && y>p[(k-1)*4+1].y) || y>p[(4*k-1)].y ) return 1; } return 0;}T d(Pt a,Pt b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}int main(){ int n = 0,i = 0,j = 0; T x = 0,y = 0; float bst = 0; unsigned temp = 0; p0 = Pt(0,5); pn = Pt(10,5); while((scanf("%d",&n),n)!=-1) { k = 0; m = 1; xs[0] = 0; for(i = 0;i<n;i++) { scanf("%f",&x); xs[m++] = x; for(j = 0;j<4;j++) { scanf("%f",&y); p[k++] = Pt(x,y); } } if(!segments(p0,pn,0,k)) { pn.len = d(pn,p0); printf("%.2f\n",pn.len); continue; } for(i = 0;i<k;i++) { bst = (~temp)>>1; if(i/4 == 0) p[i].len = d(p[i],p0); else { if(!segments(p[i],p0,0,i)) { p[i].len = d(p[i],p0); continue; } for(j = 0;j<=(i/4)*4-1;j++) { if(!segments(p[i],p[j],j,i)) if(d(p[i],p[j])+p[j].len<bst) bst = d(p[i],p[j])+p[j].len; } p[i].len = bst; } } bst = (~temp)>>1; for(i = 0;i<k;i++) { if(!segments(p[i],pn,i,k)) if(d(p[i],pn)+p[i].len<bst) bst = d(p[i],pn)+p[i].len; } printf("%.2f\n",bst); } return 0;}
- poj 1556
- POJ 1556
- poj 1556
- poj 1556
- poj 1556
- (1556)POJ
- poj 1556
- POJ 1556
- poj 1556 The Doors
- poj 1556 The Doors
- POJ 1556 The Doors
- poj 1556 The Doors
- poj 1556 The Doors
- POJ 1556 线段相交
- Poj 1556 The Doors
- poj 1556 &zoj 1721
- poj 1556(floyd)
- POJ 1556 The Doors
- Java程序员不该有的6种陋习(转自51cto.com)
- 抓包修改后上传数据
- Spring3 MVC 配置详解
- jQuery插件之Tabpanel
- yii php框架研究学习
- POJ 1556
- navigator.geolocation 基于google map的应用
- 数据结构与算法之—数组(二)
- ORACLE 数据查询集合即:查询结果的集合操作 并集 交集 差集
- mysql aud - it访问日志记录
- jQuery 插件之Checkbox
- jsp <c:set>标签的使用
- HDU 1856
- 下拉框 单选按钮