传送门:Treasure Hunt
题意
有一个左下角为(0,0),右上角为(100,100)的正方形,给出n条线段,线段的起点和终点都在正方形上,给定一个宝藏的坐标,问从正方形外走到宝藏至少要经过多少条线段。每次只能走线段的中点,也就是每两个交点的中点。
题解
因为肯定是从正方形的边开始走,所以枚举每条边上的相邻两个点的中点,连接宝藏所在的点,看这条线段和几条线段有交点,并更新最小值。(为什么这么做是对的呢?因为我没找到反例(逃
存每条边上的点时记得排序 : ) ,忘记排序花式wa。
代码
1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<string.h> 5 #include<math.h> 6 #define eps 1e-6 7 using namespace std; 8 9 struct point 10 { 11 double x,y; 12 }; 13 14 struct line 15 { 16 point s,t; 17 }l[1000]; 18 19 double a[10010]; 20 21 double cross(point a,point b) 22 { 23 return a.x*b.y-a.y*b.x; 24 } 25 26 point operator - (point a,point b) 27 { 28 return {a.x-b.x,a.y-b.y}; 29 } 30 31 bool intersection(point a,point b,point c,point d) 32 { 33 //快速排斥实验 34 if(max(c.x,d.x)<min(a.x,b.x)||max(a.x,b.x)<min(c.x,d.x)||max(c.y,d.y)<min(a.y,b.y)||max(a.y,b.y)<min(c.y,d.y)){ 35 return false; 36 } 37 //跨立实验 38 if(cross(a-d,c-d)*cross(b-d,c-d)>0||cross(d-b,a-b)*cross(c-b,a-b)>0){ 39 return false; 40 } 41 return true; 42 } 43 44 int dcmp(double x) 45 { 46 return fabs(x)<eps?0:x<0?-1:1; 47 } 48 49 int main() 50 { 51 int n; 52 scanf("%d",&n); 53 for(int i=0;i<n;i++){ 54 scanf("%lf%lf%lf%lf",&l[i].s.x,&l[i].s.y,&l[i].t.x,&l[i].t.y); 55 } 56 l[n++]={{0,0},{0,100}}; 57 l[n++]={{0,0},{100,0}}; 58 l[n++]={{100,100},{0,100}}; 59 l[n++]={{100,100},{100,0}}; 60 point q; 61 scanf("%lf%lf",&q.x,&q.y); 62 line p; 63 int ans=0x3f3f3f3f; 64 int k=0; 65 for(int i=0;i<n;i++){ 66 if(dcmp(l[i].s.x)==0){ 67 a[k++]=l[i].s.y; 68 } 69 if(dcmp(l[i].t.x)==0){ 70 a[k++]=l[i].t.y; 71 } 72 } 73 sort(a,a+k); 74 for(int i=1;i<k;i++){ 75 p.s={0,(a[i]+a[i-1])/2.0}; 76 p.t=q; 77 int cnt=0; 78 for(int j=0;j<n;j++){ 79 if(intersection(p.s,p.t,l[j].s,l[j].t)) cnt++; 80 } 81 ans=min(ans,cnt); 82 } 83 k=0; 84 for(int i=0;i<n;i++){ 85 if(dcmp(l[i].s.y)==0){ 86 a[k++]=l[i].s.x; 87 } 88 if(dcmp(l[i].t.y)==0){ 89 a[k++]=l[i].t.x; 90 } 91 } 92 sort(a,a+k); 93 for(int i=1;i<k;i++){ 94 p.s={(a[i]+a[i-1])/2.0,0.0}; 95 p.t=q; 96 int cnt=0; 97 for(int j=0;j<n;j++){ 98 if(intersection(p.s,p.t,l[j].s,l[j].t)) cnt++; 99 } 100 ans=min(ans,cnt); 101 } 102 k=0; 103 for(int i=0;i<n;i++){ 104 if(dcmp(l[i].s.x-100)==0){ 105 a[k++]=l[i].s.y; 106 } 107 if(dcmp(l[i].t.x-100)==0){ 108 a[k++]=l[i].t.y; 109 } 110 } 111 sort(a,a+k); 112 for(int i=1;i<k;i++){ 113 p.s={100,(a[i]+a[i-1])/2.0}; 114 p.t=q; 115 int cnt=0; 116 for(int j=0;j<n;j++){ 117 if(intersection(p.s,p.t,l[j].s,l[j].t)) cnt++; 118 } 119 ans=min(ans,cnt); 120 } 121 122 k=0; 123 for(int i=0;i<n;i++){ 124 if(dcmp(l[i].s.y-100)==0){ 125 a[k++]=l[i].s.x; 126 } 127 if(dcmp(l[i].t.y-100)==0){ 128 a[k++]=l[i].t.x; 129 } 130 } 131 sort(a,a+k); 132 for(int i=1;i<k;i++){ 133 p.s={(a[i]+a[i-1])/2.0,100}; 134 p.t=q; 135 int cnt=0; 136 for(int j=0;j<n;j++){ 137 if(intersection(p.s,p.t,l[j].s,l[j].t)) cnt++; 138 } 139 ans=min(ans,cnt); 140 } 141 if(q.x<0||q.x>100||q.y<0||q.y>100) ans=0; 142 printf("Number of doors = %d ",ans); 143 return 0; 144 }