USACO 3.4 Closed Fences (计算几何)

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

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

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

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

USACO 3.4 Closed Fences (计算几何)

  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 }

 

你可能感兴趣的:(USACO)