这个题卡了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 }