2014 辽宁 ACM 省赛 ( kuangbin oj 1020)|| Distance(两点式直线公式或直线求交点
2015-03-29 13:21
323 查看
少了一个等于号wa了数十发一直没有检查出来,我的内心几乎是崩溃的。
给你一个100*100的矩形,再给你两点,求这两点确定的一条直线被这个矩形所截的长度。
矩形的四个顶点为定点,(0,0) (0,100) (100,0) (100,100)
使用两点式直线公式,可以推出第三点的坐标。注意下一分母不能为0。判断一下直线是如何走向的就好了。
原来的想法是,求出直线和四条边所在的线段交点,再求处这两点之间的长度。WA,至今没有找出错在哪里。下次再改这种思路的代码。
3/30附上:
斜对角线会存在四个交点,前两个和后两个都是一样的,如果按照原来的算法写呢么长度就会变成0.00.排序一下电集,去重在将头两个点算长度就OK了。wa了两天,第二种直线求交点的方法也过了。
这题进度要求不高 直接两个浮点数相等也过了 = = 省得我麻烦些精度误差了。
1020: Distance
时间限制: 1 Sec 内存限制: 32 MB提交: 88 解决: 19
[提交][状态][讨论版]
题目描述
There is a battle field. It is a square with the side length 100 miles, and unfortunately we have two comrades who get hurt still in the battle field. They are in different positions. You have to save them. Now I give youthe positions of them, and you should choose a straight way and drive a car to get them. Of course you should cross the battle field, since it is dangerous, you want to leave it as quickly as you can!
输入
There are many test cases. Each test case contains four floating number, indicating the two comrades' positions (x1,y1), (x2,y2).Proceed to the end of file.
输出
you should output the mileage which you drive in the battle field. The result should be accurate up to 2 decimals.样例输入
1.0 2.0 3.0 4.015.0 23.0 46.5 7.0
样例输出
140.0
167.61
提示
The battle field is a square local at (0,0),(0,100),(100,0),(100,100).#include<cmath> #include<cstdio> #include<cstdio> #include<algorithm> using namespace std; double getx( double y, double x0,double y0,double x1,double y1) { //printf("%lf %lf\n",y-y0,y0-y1); return ( (y-y0)/(y0-y1)*(x0-x1) +x0 ); } double gety( double x,double x0,double y0,double x1,double y1) { return ( (x-x0)/(x0-x1)*(y0-y1) + y0); } double getlen( double x,double y,double x1,double y1) { return sqrt( (x-x1)*(x-x1) + (y-y1)* (y-y1)); } int main() { double x0,x1,y0,y1; while( ~scanf("%lf %lf %lf %lf",&x0,&y0,&x1,&y1)) { if( x1 < x0 ) { swap(x1,x0); swap(y1,y0); } if( (x0==x1)||(y0==y1)) { puts("100.00"); continue; } double x,xn,y,yn; x = 0.0; xn = 100.0; y = gety( x,x0,y0,x1,y1 ); yn = gety( xn,x0,y0,x1,y1); //printf( "%lf %lf\n",y,yn); if( (yn>100 || yn <0) &&(y>=0 && y<=100) ) { if( yn > 100) yn = 100.0; else yn = 0.0; xn = getx(yn,x0,y0,x1,y1); } else if( ( y <0 || y >100 ) && ( yn>=0 && yn <=100) ) { if ( y < 0 ) y = 0.0; else y = 100; x = getx( y,x0,y0,x1,y1); } else if( y > 100 && yn<0 ) { y = 100; yn = 0; x = getx(y,x0,y0,x1,y1); xn = getx(yn,x0,y0,x1,y1); } else if( y < 0 && yn > 100) { y = 0; yn = 100; x = getx(y,x0,y0,x1,y1); xn = getx(yn,x0,y0,x1,y1); } //printf("x=%lf y=%lf xn=%lf yn=%lf\n",x,y,xn,yn); double ans = getlen(x,y,xn,yn); printf("%.2lf\n",ans); } }
直线求交点代码:
#include<cstdio> #include<algorithm> #include<cmath> using namespace std; struct pnode { float x,y; pnode(){} pnode( double a,double b):x(a),y(b){} float operator ^ (const pnode &b)const { return x*b.y - b.x*y; } pnode operator - ( const pnode &b)const { return pnode( x-b.x,y-b.y); } pnode operator * (const double p)const { return pnode(x*p,y*p); } pnode operator + (const pnode&b)const { return pnode(x+b.x,y+b.y); } bool operator == (const pnode&b)const { return x==b.x && y ==b.y; } bool operator < (const pnode&b)const { return (x==b.x)?y <b.y:x<b.x; } bool operator > (const pnode&b)const { return ( x==b.x)?y>b.y:x>b.x; } }; pnode p1,p2; struct pline { pnode st,ed; pline(){} pline(pnode a,pnode b):st(a),ed(b){} }; pline dicesiont[5] = { pline( pnode(0,0), pnode(0,100)), pline( pnode(0,100), pnode(100,100)), pline( pnode(100,100), pnode(100,0)), pline( pnode( 100,0), pnode( 0,0)) }; float cross( pnode p0,pnode p1,pnode p2) { return (p1-p0) ^ (p2-p0); } float cross( pline a,pline b) { return (a.ed - a.st) ^( b.ed-b.st); } float dot( pnode a,pnode b) { pnode tmp = b -a; return tmp.x * tmp.x + tmp.y *tmp.y; } typedef pnode vec; const float eps = 1e-5; int dcmp( float x) { if( fabs(x)<eps) return 0; return x < 0 ? -1: 1; } pnode get_line_inter_point(pline a,pline b ) { vec u = a.st - b.st; pnode tmp = b.ed - b.st; float t = ( tmp.x *u.y - tmp.y*u.x)/cross(a,b); return a.st + (a.ed-a.st)*t; } bool seg_inter_line(pline L,pline seg) { return ( dcmp( cross( seg.st,L.st,L.ed ) ) * dcmp( cross( seg.ed,L.st,L.ed) ) )<=0; } int main() { while( ~scanf("%f %f %f %f",&p1.x,&p1.y,&p2.x,&p2.y)) { float ans = 0.0; pline myline = pline( p1,p2 ); if( p1.x== p2.x || p1.y == p2.y) { puts("100.00"); continue; } else { pnode p[5]; int id = 0; for( int i = 0;i< 4;++i) { if( seg_inter_line(myline,dicesiont[i])) { p[id++] = get_line_inter_point( myline,dicesiont[i] ); } } sort(p,p+id); unique(p,p+id); ans = sqrt( dot(p[0],p[1])); } printf("%.2f\n",ans); } return 0; }
相关文章推荐
- 2014辽宁ACM省赛 Distance
- 2014辽宁ACM省赛 Lucky Numbers
- kuangbin OJ 1217-- Operations on Grids(YY)(好题)
- 直线的交点公式
- 由两点确定的直线,得到与图边界的交点
- YT03-递推求解课后题目-1004 计算直线的交点数-(6.7日-烟台大学ACM预备队解题报告)分析: 将n 条直线排成一个序列,两条直线最多只有一个交点,三条直线最多有两个交点,直线n 和其他n
- 已知两点经纬度和高度,求两点直线距离公式
- 数论?? 数学 计算直线的交点数 DBSDFZ OJ
- 2014寒假ACM集训13级PK赛-最佳拟合直线
- 2014辽宁ACM省赛 Guess
- 【转】2014区域赛小结(牡丹江&&鞍山)by kuangbin
- 已知两条直线上各两点坐标,求两条直线交点坐标
- ACM——计算直线的交点数
- 直线方程的点斜式、两点式、斜截式的公式是什么
- [ACM] hdu 2857 Mirror and Light (对称点+两条直线的交点)
- 杭电ACM-HDOJ1466计算直线的交点数(动态规划)
- 2014辽宁ACM省赛 Prime Factors
- [ACM] hdu 2857 Mirror and Light (对称点+两条直线的交点)
- 2014辽宁ACM省赛 Prime Factors
- 15HD_OJ——计算直线的交点数