• poj 2826 An Easy Problem?! (线段相交问题终极版...并不easy)


    An Easy Problem?!
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 11066   Accepted: 1673

    Description

    It's raining outside. Farmer Johnson's bull Ben wants some rain to water his flowers. Ben nails two wooden boards on the wall of his barn. Shown in the pictures below, the two boards on the wall just look like two segments on the plane, as they have the same width. 

    Your mission is to calculate how much rain these two boards can collect. 

    Input

    The first line contains the number of test cases. 
    Each test case consists of 8 integers not exceeding 10,000 by absolute value, x1y1x2y2x3y3x4y4. (x1y1), (x2y2) are the endpoints of one board, and (x3y3), (x4y4) are the endpoints of the other one. 

    Output

    For each test case output a single line containing a real number with precision up to two decimal places - the amount of rain collected. 

    Sample Input

    2
    0 1 1 0
    1 0 2 1
    
    0 1 2 1
    1 0 1 2
    

    Sample Output

    1.00
    0.00

    感动到cry。。。终于A掉了。
    我的做法是这样的:
    有三个重要的点,一个是两条线段的交点,设为crossp
    第二个是末端点中较低的点(所以读入的时候adjust一下,线段方向维护成由低指向高),设为lowp
    第三个是由lowp做平行线,交到另一条直线(anotherline)得到点p3

    雨是垂直下落。
    一般的情况只要求这三个点组成的三角形的面积就行了(叉积或者h*c/2都可以) 两种写法都可以A
    主要是一些误解情况的判断。

    首先,不相交的话,肯定无解。
    所以先判断下相交。

    细分的话,如果有一条直线平行x轴,那么肯定无解。

    接下来是,crossp正好和lowp重合,肯定无解。

    然而如果用c*h/2的话,2,3两种情况可以不用单独考虑,因为会得出h==0,答案自然为0

    接下来比较难想到的是,口被封住的情况。

    虽然我想到了这种情况,但是判定条件想错了。

    我误以为两个末端点在p3的同侧的话,口就会无解。

    但如下图

    这种情况却是有解的,答案不为0

    这步判定想错是我WA了多次最主要的原因QAQ

    不过只要稍微改动下就好

    只有x在lowp那条线的左边且lowp在anotherline末端点的左边

    或者x在lowp那条线的右边且lowp在anotherline末端点的右边  口才会被封住。 

    1     int sameside(point p1,point p2)
    2     {
    3 //    p1.output();
    4 //    p2.output();
    5     if (dblcmp(x-p2.x)<=0&&dblcmp(p2.x-p1.x)<=0) return 1;
    6     if (dblcmp(x-p2.x)>=0&&dblcmp(p2.x-p1.x)>=0) return 1;
    7     return 0;
    8     }
    因为一个细节又WA了一次。
    上面的代码一开始忘写了等号。
    如果但实际上末端点的横坐标相等,也是无解的。

      1 /*************************************************************************
      2     > File Name: code/poj/2826.cpp
      3     > Author: 111qqz
      4     > Email: rkz2013@126.com 
      5     > Created Time: 2015年11月06日 星期五 16时07分21秒
      6  ************************************************************************/
      7 
      8 #include<iostream>
      9 #include<iomanip>
     10 #include<cstdio>
     11 #include<algorithm>
     12 #include<cmath>
     13 #include<cstring>
     14 #include<string>
     15 #include<map>
     16 #include<set>
     17 #include<queue>
     18 #include<vector>
     19 #include<stack>
     20 #include<cctype>
     21 #define fst first              
     22 #define sec second      
     23 #define lson l,m,rt<<1
     24 #define rson m+1,r,rt<<1|1
     25 #define ms(a,x) memset(a,x,sizeof(a))
     26 using namespace std;
     27 const double eps = 1E-10;
     28 const int dx4[4]={1,0,0,-1};
     29 const int dy4[4]={0,-1,1,0};
     30 typedef long long LL;
     31 const int inf = 0x3f3f3f3f;
     32 const double pi = acos(-1.0);
     33 int dblcmp(double d)
     34 {
     35     return d < -eps ? -1 : d > eps;
     36 }
     37 inline double sqr(double x){return x*x;}
     38 struct point
     39 {
     40     double x,y;
     41     point(){}
     42     point(double _x,double _y):
     43     x(_x),y(_y){};
     44     void input()
     45     {
     46         scanf("%lf%lf",&x,&y);
     47     }
     48     void output()
     49     {
     50         printf("%.2f %.2f
    ",x,y);
     51     }
     52     bool operator==(point a)const
     53     {
     54         return dblcmp(a.x-x)==0&&dblcmp(a.y-y)==0;
     55     }
     56     bool operator<(point a)const
     57     {
     58         return dblcmp(a.x-x)==0?dblcmp(y-a.y)<0:x<a.x;
     59     }
     60     double len()
     61     {
     62         return hypot(x,y);
     63     }
     64     double len2()
     65     {
     66         return x*x+y*y;
     67     }
     68     double distance(point p)
     69     {
     70         return hypot(x-p.x,y-p.y);
     71     }
     72     double distance2(point p)
     73     {
     74         return sqr(x-p.x)+sqr(y-p.y);
     75     }
     76     point add(point p)
     77     {
     78         return point(x+p.x,y+p.y);
     79     }
     80     point operator + (const point & p) const{
     81         return point(x+p.x,y+p.y);
     82     }
     83     point sub(point p)
     84     {
     85         return point(x-p.x,y-p.y);
     86     }
     87     point operator - (const point & p) const{
     88         return point(x-p.x,y-p.y);
     89     }
     90     point mul(double b)
     91     {
     92         return point(x*b,y*b);
     93     }
     94     point div(double b)
     95     {
     96         return point(x/b,y/b);
     97     }
     98     double dot(point p)
     99     {
    100         return x*p.x+y*p.y;
    101     }
    102     double operator * (const point & p) const{
    103         return x*p.x+y*p.y;
    104     }
    105     double det(point p)
    106     {
    107         return x*p.y-y*p.x;
    108     }
    109     double operator ^ (const point & p) const{
    110         return x*p.y-y*p.x;
    111     }
    112     double rad(point a,point b)
    113     {
    114         point p=*this;
    115         return fabs(atan2(fabs(a.sub(p).det(b.sub(p))),a.sub(p).dot(b.sub(p))));
    116     }
    117     point trunc(double r)
    118     {
    119         double l=len();
    120         if (!dblcmp(l))return *this;
    121         r/=l;
    122         return point(x*r,y*r);
    123     }
    124     point rotleft()
    125     {
    126         return point(-y,x);
    127     }
    128     point rotright()
    129     {
    130         return point(y,-x);
    131     }
    132     point rotate(point p,double angle)//绕点p逆时针旋转angle角度
    133     {
    134         point v=this->sub(p);
    135         double c=cos(angle),s=sin(angle);
    136         return point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
    137     }
    138 
    139     int sameside(point p1,point p2)
    140     {
    141 //    p1.output();
    142 //    p2.output();
    143     if (dblcmp(x-p2.x)<=0&&dblcmp(p2.x-p1.x)<=0) return 1;
    144     if (dblcmp(x-p2.x)>=0&&dblcmp(p2.x-p1.x)>=0) return 1;
    145     return 0;
    146     }
    147     double gettrianglearea(point b,point c)
    148     {
    149     return ((b.x-x)*(c.y-y)-(b.y-y)*(c.x-x))/2;
    150     }
    151 };
    152 struct line
    153 {
    154     point a,b;
    155     line(){}
    156     line(point _a,point _b)
    157     {
    158         a=_a;
    159         b=_b;
    160     }
    161     bool operator==(line v)
    162     {
    163         return (a==v.a)&&(b==v.b);
    164     }
    165     //倾斜角angle
    166     line(point p,double angle)
    167     {
    168         a=p;
    169         if (dblcmp(angle-pi/2)==0)
    170         {
    171             b=a.add(point(0,1));
    172         }
    173         else
    174         {
    175             b=a.add(point(1,tan(angle)));
    176         }
    177     }
    178     //ax+by+c=0
    179     line(double _a,double _b,double _c)
    180     {
    181         if (dblcmp(_a)==0)
    182         {
    183             a=point(0,-_c/_b);
    184             b=point(1,-_c/_b);
    185         }
    186         else if (dblcmp(_b)==0)
    187         {
    188             a=point(-_c/_a,0);
    189             b=point(-_c/_a,1);
    190         }
    191         else
    192         {
    193             a=point(0,-_c/_b);
    194             b=point(1,(-_c-_a)/_b);
    195         }
    196     }
    197     void input()
    198     {
    199         a.input();
    200         b.input();
    201     }
    202     void adjust()  //调整为由低指向高
    203     {
    204     if (dblcmp(a.y-b.y)>0) swap(a,b);
    205     }
    206     double length()
    207     {
    208         return a.distance(b);
    209     }
    210     double getk()
    211     {
    212 //    printf("*********
    a.x: %f a.y %f b.x : %f b.y : %f
     ****************
    ",a.x,a.y,b.x,b.y);
    213     return (b.y-a.y)/(b.x-a.x);
    214     }
    215     double angle()//直线倾斜角 0<=angle<180
    216     {
    217         double k=atan2(b.y-a.y,b.x-a.x);
    218         if (dblcmp(k)<0)k+=pi;
    219         if (dblcmp(k-pi)==0)k-=pi;
    220 //        cout<<"ang1:"<<k<<endl;
    221 //        cout<<"k:"<<tan(k)<<endl;
    222         return k;
    223     }
    224     //点和线段关系
    225     //1 在逆时针
    226     //2 在顺时针
    227     //3 平行
    228     int relation(point p)
    229     {
    230         int c=dblcmp(p.sub(a).det(b.sub(a)));
    231         if (c<0)return 1;
    232         if (c>0)return 2;
    233         return 3;
    234     }
    235     bool pointonseg(point p)
    236     {
    237         return dblcmp(p.sub(a).det(b.sub(a)))==0&&dblcmp(p.sub(a).dot(p.sub(b)))<=0;
    238     }
    239     bool parallel(line v)
    240     {
    241         return dblcmp(b.sub(a).det(v.b.sub(v.a)))==0;
    242     }
    243     //2 规范相交
    244     //1 非规范相交 ()
    245     //0 不相交
    246     int segcrossseg(line v)
    247     {
    248         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
    249         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
    250         int d3=dblcmp(v.b.sub(v.a).det(a.sub(v.a)));
    251         int d4=dblcmp(v.b.sub(v.a).det(b.sub(v.a)));
    252         if ((d1^d2)==-2&&(d3^d4)==-2)return 2;
    253         return (d1==0&&dblcmp(v.a.sub(a).dot(v.a.sub(b)))<=0||
    254                 d2==0&&dblcmp(v.b.sub(a).dot(v.b.sub(b)))<=0||
    255                 d3==0&&dblcmp(a.sub(v.a).dot(a.sub(v.b)))<=0||
    256                 d4==0&&dblcmp(b.sub(v.a).dot(b.sub(v.b)))<=0);
    257     }
    258     int linecrossseg(line v)//*this seg v line
    259     {
    260         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
    261         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
    262         if ((d1^d2)==-2)return 2;
    263         return (d1==0||d2==0);
    264     }
    265     point crosspoint(line v)
    266     {
    267         double a1=v.b.sub(v.a).det(a.sub(v.a));
    268         double a2=v.b.sub(v.a).det(b.sub(v.a));
    269         return point((a.x*a2-b.x*a1)/(a2-a1),(a.y*a2-b.y*a1)/(a2-a1));
    270     }
    271 }li[10];
    272 int main()
    273 {
    274   #ifndef  ONLINE_JUDGE 
    275    freopen("in.txt","r",stdin);
    276   #endif
    277 
    278    int T;
    279    scanf("%d",&T);
    280    while (T--)
    281    {                                          
    282     li[1].input();li[1].adjust();
    283     li[2].input();li[2].adjust();
    284     if (li[1].segcrossseg(li[2])==0)  //不相交
    285     {
    286         puts("0.00");
    287         continue;
    288     }
    289     
    290     point crossp=li[1].crosspoint(li[2]);
    291     point lowp;
    292     int anotherline;
    293     if (li[1].b.y<li[2].b.y)
    294     {
    295         lowp=li[1].b;
    296         anotherline=2;
    297     }
    298     else
    299     {
    300         lowp=li[2].b;
    301         anotherline=1 ;
    302     }
    303 
    304     point p3;
    305     if (dblcmp(li[anotherline].a.x-li[anotherline].b.x)==0)
    306     {
    307         p3.x=li[anotherline].a.x;
    308         p3.y=lowp.y;
    309     }
    310     else
    311     {
    312         double dy =lowp.y-li[anotherline].a.y;
    313         double k = li[anotherline].getk();
    314         p3.x=li[anotherline].a.x+dy*1.0/k;
    315         p3.y=lowp.y;
    316     }
    317     double h = lowp.y-crossp.y;
    318     if (dblcmp(h)==0)
    319     {
    320         puts("0.00");
    321         continue;
    322     }
    323     if (p3.sameside(li[anotherline].b,li[anotherline%2+1].b)==1)
    324     {
    325         puts("0.00");
    326         continue;
    327     }
    328     double c = fabs(lowp.x-p3.x);
    329     
    330     double ans = h*c/2;
    331 //    double ans = lowp.gettrianglearea(crossp,p3);
    332     printf("%.2f
    ",fabs(ans));
    333 
    334 
    335    }
    336   
    337    
    338  #ifndef ONLINE_JUDGE  
    339   #endif
    340   fclose(stdin);
    341     return 0;
    342 }
    View Code







  • 相关阅读:
    cocos2dx 3.x(获取当前系统时间)
    cocos2dx 3.x(加载cocostudio进度条)
    cocos2dx 3.x(Button传统按钮)
    cocos2dx 3.x以上(Sprite精灵类的相关属性与创建)
    cocos2dx 3.x版本搭建Mac环境工程(创建一个新的C++工程)百分百可行
    iOS
    iOS -Swift 3.0 -Array(数组与可变数组相关属性及用法)
    iOS -Swift 3.0 -String(字符串常规用法)
    iOS -Swift 3.0 -UIButton属性大全
    iOS -Swift 3.0 -UILabel属性大全
  • 原文地址:https://www.cnblogs.com/111qqz/p/4945787.html
Copyright © 2020-2023  润新知