POJ - 2826 An Easy Problem?!(计算几何,好题)
生活随笔
收集整理的這篇文章主要介紹了
POJ - 2826 An Easy Problem?!(计算几何,好题)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題目鏈接:點(diǎn)擊查看
題目大意:給出兩條線段,問組成的容器最多能接多少雨水
題目分析:既然是接雨水,那么肯定只能是漏斗狀,很容易排除掉兩種情況:
還有一種比較難想的情況kuangbin大神提到了,那就是封口的情況,對(duì)應(yīng)就是以下三種情況:
單獨(dú)討論之后,剩下的情況就一定有解了,直接按照三角形的面積計(jì)算就是答案了
注意結(jié)果需要加上一個(gè)eps防止出現(xiàn)-0.00的情況,我猜的,不加的話會(huì)WA,加上就A了,玄學(xué)
代碼:
#include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<queue> #include<map> #include<set> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=60;const double eps = 1e-8;int sgn(double x){if(fabs(x) < eps)return 0;if(x < 0)return -1;else return 1; }struct Point{double x,y;Point(){}Point(double _x,double _y){x = _x;y = _y;}void input(){scanf("%lf%lf",&x,&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;}//點(diǎn)積double operator *(const Point &b)const{return x*b.x + y*b.y;}//返回兩點(diǎn)的距離double distance(Point p){return hypot(x-p.x,y-p.y);} };struct Line{Point s,e;Line(){}Line(Point _s,Point _e){s = _s;e = _e;}void input(){s.input();e.input();}//求線段長(zhǎng)度double length(){return s.distance(e);}//`兩線段相交判斷`//`2 規(guī)范相交`//`1 非規(guī)范相交`//`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)==-2 && (d3^d4)==-2 )return 2;return (d1==0 && sgn((v.s-s)*(v.s-e))<=0) ||(d2==0 && sgn((v.e-s)*(v.e-e))<=0) ||(d3==0 && sgn((s-v.s)*(s-v.e))<=0) ||(d4==0 && sgn((e-v.s)*(e-v.e))<=0);}//`直線和線段相交判斷`//`-*this line -v seg`//`2 規(guī)范相交`//`1 非規(guī)范相交`//`0 不相交`int linecrossseg(Line v){int d1 = sgn((e-s)^(v.s-s));int d2 = sgn((e-s)^(v.e-s));if((d1^d2)==-2) return 2;return (d1==0||d2==0);}//`求兩直線的交點(diǎn)`//`要保證兩直線不平行或重合`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));}//點(diǎn)到直線的距離double dispointtoline(Point p){return fabs((p-s)^(e-s))/length();} }l1,l2;int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);int w;cin>>w;while(w--){l1.input();l2.input();if(sgn(l1.s.y-l1.e.y)==0||sgn(l2.s.y-l2.e.y)==0)//有一條線平行于x軸 {puts("0.00");continue;}if(sgn(l1.s.y-l1.e.y)<0)swap(l1.s,l1.e);if(sgn(l2.s.y-l2.e.y)<0)swap(l2.s,l2.e);if(l1.segcrossseg(l2)==0)//不相交 {puts("0.00");continue;}if(l1.segcrossseg(Line(Point(l2.s.x,100000),l2.s))||l2.segcrossseg(Line(Point(l1.s.x,100000),l1.s)))//口被封上 {puts("0.00");continue;}double ans1=1e10,ans2=1e10;Point point=l1.crosspoint(l2);//交點(diǎn)Line temp1=Line(l2.s,Point(100000,l2.s.y));//與x軸平行,且過l2上面的點(diǎn)的直線 Line temp2=Line(l1.s,Point(100000,l1.s.y));//與x軸平行,且過l1上面的點(diǎn)的直線 if(temp1.linecrossseg(l1)){Point temp=temp1.crosspoint(l1);//當(dāng)前三個(gè)點(diǎn)構(gòu)成三角形temp point l2.s ans1=0.5*(temp1.dispointtoline(point)*temp.distance(l2.s));}if(temp2.linecrossseg(l2)){Point temp=temp2.crosspoint(l2);//當(dāng)前三個(gè)點(diǎn)構(gòu)成三角形temp point l1.s ans2=0.5*(temp2.dispointtoline(point)*temp.distance(l1.s));}printf("%.2f\n",min(ans1,ans2)+eps);}return 0; }?
總結(jié)
以上是生活随笔為你收集整理的POJ - 2826 An Easy Problem?!(计算几何,好题)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ - 3347 Kadj Squa
- 下一篇: POJ - 1584 A Round P