zoukankan      html  css  js  c++  java
  • POJ

    传送门: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 }
  • 相关阅读:
    几个C#编程的小技巧
    用asp.net实现将上传的图片变小存入数据库
    解决sql server安装问题
    Linux三则超酷技巧
    vc编程参考站点,简要的Windows API函数大全
    声明游标
    如何把string解析为int?[C#] How to Parse a string to an int? [C#]
    SQL Server2000数据库系统表的应用
    胶囊和凸多边形的动态碰撞检测
    纹理资源管理的困惑
  • 原文地址:https://www.cnblogs.com/lilibuxiangtle/p/13740680.html
Copyright © 2011-2022 走看看