现在的位置: 首页 > 综合 > 正文

POJ 1556

2013年03月22日 ⁄ 综合 ⁄ 共 2886字 ⁄ 字号 评论关闭

题目链接: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;
}
【上篇】
【下篇】

抱歉!评论已关闭.