POJ - 1066 Treasure Hunt

传送门: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\n",ans);
143     return 0;
144 }

 

posted @ 2020-09-27 17:21  只能过样例嘤嘤嘤  阅读(166)  评论(0编辑  收藏  举报

……