USACO 3.4 Closed Fences (计算几何)

这个题卡了3个月啊,看了题解依旧不会写。。。从中找了一个思路比较简单,而且好写的,把每个顶点,左右微调一下,然后找出穿过起点到微调后的点  最近的边,一定可以看见。

这个算法正确性,我不太确定,确实可以把所有数据过掉。。

调了好久,好久,各种变量名敲错啊,后边大部分全是抄的。。。

第三章终于做完了。。。那3个很快就水过了。。

  1 /*
  2       ID: cuizhe
  3       LANG: C++
  4       TASK: fence4
  5 */
  6 #include <cstdio>
  7 #include <cstring>
  8 #include <iostream>
  9 #include <cmath>
 10 using namespace std;
 11 #define eps 1e-5
 12 #define C 1e8
 13 #define INF 1e15
 14 #define pi acos(-1.0)
 15 struct point
 16 {
 17     double x,y;
 18     point (double a = 0,double b = 0)
 19     {
 20         x = a;
 21         y = b;
 22     }
 23 }o,p[501];
 24 int see[501],n;
 25 struct line
 26 {
 27     point a,b;
 28 };
 29 double det(double x1,double y1,double x2,double y2)
 30 {
 31     return x1*y2 - x2*y1;
 32 }
 33 double cross(point a,point b,point c)
 34 {
 35     return det(a.x-c.x,a.y-c.y,b.x-c.x,b.y-c.y);
 36 }
 37 int dblcmp(double a)
 38 {
 39     if(fabs(a) < eps)
 40     return 0;
 41     return a > 0 ? 1:-1;
 42 }
 43 double dotdet(double x1,double y1,double x2,double y2)
 44 {
 45     return x1*x2 + y1*y2;
 46 }
 47 double dot(point a,point b,point c)
 48 {
 49     return dotdet(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);
 50 }
 51 int betweenCmp(point a,point b,point c)//?D??aμ?ê?·??úbcé?
 52 {
 53     return dblcmp(dot(a,b,c));
 54 }
 55 int segcross(point a,point b,point c,point d,point &p)
 56 {
 57     double s1,s2,s3,s4;
 58     int d1,d2,d3,d4;
 59     d1 = dblcmp(s1 = cross(a,b,c));
 60     d2 = dblcmp(s2 = cross(a,b,d));
 61     d3 = dblcmp(s3 = cross(c,d,a));
 62     d4 = dblcmp(s4 = cross(c,d,b));
 63     if((d1^d2) == -2&&(d3^d4) == -2)
 64     {
 65         p.x = (c.x*s2 - d.x*s1)/(s2 - s1);
 66         p.y = (c.y*s2 - d.y*s1)/(s2 - s1);
 67         return 1;
 68     }
 69     return 0;
 70 }
 71 double dis(point a,point b)
 72 {
 73     return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
 74 }
 75 void nearest(double xx,double yy)
 76 {
 77     double t,minz = INF;
 78     int i,near = -1;
 79     point inter,pt(xx,yy);
 80     pt.x += (pt.x-o.x)*C;
 81     pt.y += (pt.y-o.y)*C;
 82     for(i = 0; i < n; ++i)
 83     {
 84         if(!segcross(o,pt,p[i],p[(i+1)%n],inter))continue;
 85         t = dis(inter,o);
 86         if(minz > t)
 87         {
 88             minz = t;
 89             near = i;
 90         }
 91     }
 92     if(near != -1)
 93     {
 94         see[near] = 1;
 95     }
 96 }
 97 int main()
 98 {
 99     freopen("fence4.in","r",stdin);
100     freopen("fence4.out","w",stdout);
101     int i,j,flag;
102     point a;
103     scanf("%d",&n);
104     scanf("%lf%lf",&o.x,&o.y);
105     for(i = 0; i < n; i ++)
106     {
107         scanf("%lf%lf",&p[i].x,&p[i].y);
108     }
109     flag = 1;
110     p[n] = p[0];
111     for(i = 0; i < n; i ++)
112     {
113         for(j = i+1; j < n; j ++)
114         {
115             if(segcross(p[i],p[(i+1)%n],p[j],p[(j+1)%n],a))
116                 flag = 0;
117         }
118     }
119     if(!flag)
120     {
121         printf("NOFENCE\n");
122         return 0;
123     }
124     for(i = 0;i < n;i ++)
125     {
126         nearest(p[i].x-10.0*eps,p[i].y-10.0*eps);
127         nearest(p[i].x+10.0*eps,p[i].y+10.0*eps);
128     }
129     int num = 0;
130     for(i = 0; i < n; ++i)
131     {
132         if(see[i])
133         num ++;
134     }
135     printf("%d\n", num);
136     for(i = 0; i < n-2; ++i)
137     {
138         if(see[i])
139         {
140             printf("%.0lf %.0lf %.0lf %.0lf\n",p[i].x,p[i].y,p[i+1].x,p[i+1].y);
141         }
142     }
143     if(see[i=n-1])
144     {
145         printf("%.0lf %.0lf %.0lf %.0lf\n",p[i+1].x,p[i+1].y,p[i].x,p[i].y);
146     }
147     if(see[i=n-2])
148     {
149         printf("%.0lf %.0lf %.0lf %.0lf\n",p[i].x,p[i].y,p[i+1].x,p[i+1].y);
150     }
151     return 0;
152 }

 

posted @ 2013-02-16 20:31  Naix_x  阅读(278)  评论(0编辑  收藏  举报