zoukankan      html  css  js  c++  java
  • Treasure Hunt

    Treasure Hunt

    http://poj.org/problem?id=1066

    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 8233   Accepted: 3402

    Description

    Archeologists from the Antiquities and Curios Museum (ACM) have flown to Egypt to examine the great pyramid of Key-Ops. Using state-of-the-art technology they are able to determine that the lower floor of the pyramid is constructed from a series of straightline walls, which intersect to form numerous enclosed chambers. Currently, no doors exist to allow access to any chamber. This state-of-the-art technology has also pinpointed the location of the treasure room. What these dedicated (and greedy) archeologists want to do is blast doors through the walls to get to the treasure room. However, to minimize the damage to the artwork in the intervening chambers (and stay under their government grant for dynamite) they want to blast through the minimum number of doors. For structural integrity purposes, doors should only be blasted at the midpoint of the wall of the room being entered. You are to write a program which determines this minimum number of doors. 
    An example is shown below: 

    Input

    The input will consist of one case. The first line will be an integer n (0 <= n <= 30) specifying number of interior walls, followed by n lines containing integer endpoints of each wall x1 y1 x2 y2 . The 4 enclosing walls of the pyramid have fixed endpoints at (0,0); (0,100); (100,100) and (100,0) and are not included in the list of walls. The interior walls always span from one exterior wall to another exterior wall and are arranged such that no more than two walls intersect at any point. You may assume that no two given walls coincide. After the listing of the interior walls there will be one final line containing the floating point coordinates of the treasure in the treasure room (guaranteed not to lie on a wall).

    Output

    Print a single line listing the minimum number of doors which need to be created, in the format shown below.

    Sample Input

    7 
    20 0 37 100 
    40 0 76 100 
    85 0 0 75 
    100 90 0 90 
    0 71 100 61 
    0 14 100 38 
    100 47 47 100 
    54.5 55.4 

    Sample Output

    Number of doors = 2 

    Source

    枚举边界上的点,要注意,枚举的步长为1会wa,步长要0.5= =

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<vector>
      6 #include<algorithm>
      7 using namespace std;
      8 const double eps=1e-8;
      9 const double INF=1e20;
     10 const double PI=acos(-1.0);
     11 const int maxp=1010;
     12 int sgn(double x){
     13     if(fabs(x)<eps) return 0;
     14     if(x<0) return -1;
     15     else return 1;
     16 }
     17 
     18 double hypot(double x,double y){
     19     return sqrt(x*x+y*y);
     20 }
     21 
     22 inline double sqr(double x){return x*x;}
     23 struct Point{
     24     double x,y;
     25     Point(){}
     26     Point(double _x,double _y){
     27         x=_x;
     28         y=_y;
     29     }
     30     void input(){
     31         scanf("%lf %lf",&x,&y);
     32     }
     33     void output(){
     34         printf("%.2f %.2f
    ",x,y);
     35     }
     36     bool operator == (const Point &b)const{
     37         return sgn(x-b.x) == 0 && sgn(y-b.y)== 0;
     38     }
     39     bool operator < (const Point &b)const{
     40         return sgn(x-b.x)==0?sgn(y-b.y)<0:x<b.x;
     41     }
     42     Point operator - (const Point &b)const{
     43         return Point(x-b.x,y-b.y);
     44     }
     45     //叉积
     46     double operator ^ (const Point &b)const{
     47         return x*b.y-y*b.x;
     48     }
     49     //点积
     50     double operator * (const Point &b)const{
     51         return x*b.x+y*b.y;
     52     }
     53     //返回长度
     54     double len(){
     55         return hypot(x,y);
     56     }
     57     //返回长度的平方
     58     double len2(){
     59         return x*x+y*y;
     60     }
     61     //返回两点的距离
     62     double distance(Point p){
     63         return hypot(x-p.x,y-p.y);
     64     }
     65     Point operator + (const Point &b)const{
     66         return Point(x+b.x,y+b.y);
     67     }
     68     Point operator * (const double &k)const{
     69         return Point(x*k,y*k);
     70     }
     71     Point operator / (const double &k)const{
     72         return Point(x/k,y/k);
     73     }
     74 
     75     //计算pa和pb的夹角
     76     //就是求这个点看a,b所成的夹角
     77     ///LightOJ1202
     78     double rad(Point a,Point b){
     79         Point p=*this;
     80         return fabs(atan2(fabs((a-p)^(b-p)),(a-p)*(b-p)));
     81     }
     82     //化为长度为r的向量
     83     Point trunc(double r){
     84         double l=len();
     85         if(!sgn(l)) return *this;
     86         r/=l;
     87         return Point(x*r,y*r);
     88     }
     89     //逆时针转90度
     90     Point rotleft(){
     91         return Point(-y,x);
     92     }
     93     //顺时针转90度
     94     Point rotright(){
     95         return Point(y,-x);
     96     }
     97     //绕着p点逆时针旋转angle
     98     Point rotate(Point p,double angle){
     99         Point v=(*this) -p;
    100         double c=cos(angle),s=sin(angle);
    101         return Point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
    102     }
    103 };
    104 
    105 struct Line{
    106     Point s,e;
    107     Line(){}
    108     Line(Point _s,Point _e){
    109         s=_s;
    110         e=_e;
    111     }
    112     bool operator==(Line v){
    113         return (s==v.s)&&(e==v.e);
    114     }
    115     //根据一个点和倾斜角angle确定直线,0<=angle<pi
    116     Line(Point p,double angle){
    117         s=p;
    118         if(sgn(angle-PI/2)==0){
    119             e=(s+Point(0,1));
    120         }
    121         else{
    122             e=(s+Point(1,tan(angle)));
    123         }
    124     }
    125     //ax+by+c=0;
    126     Line(double a,double b,double c){
    127         if(sgn(a)==0){
    128             s=Point(0,-c/b);
    129             e=Point(1,-c/b);
    130         }
    131         else if(sgn(b)==0){
    132             s=Point(-c/a,0);
    133             e=Point(-c/a,1);
    134         }
    135         else{
    136             s=Point(0,-c/b);
    137             e=Point(1,(-c-a)/b);
    138         }
    139     }
    140     void input(){
    141         s.input();
    142         e.input();
    143     }
    144     void adjust(){
    145         if(e<s) swap(s,e);
    146     }
    147     //求线段长度
    148     double length(){
    149         return s.distance(e);
    150     }
    151     //返回直线倾斜角 0<=angle<pi
    152     double angle(){
    153         double k=atan2(e.y-s.y,e.x-s.x);
    154         if(sgn(k)<0) k+=PI;
    155         if(sgn(k-PI)==0) k-=PI;
    156         return k;
    157     }
    158     //点和直线的关系
    159     //1 在左侧
    160     //2 在右侧
    161     //3 在直线上
    162     int relation(Point p){
    163         int c=sgn((p-s)^(e-s));
    164         if(c<0) return 1;
    165         else if(c>0) return 2;
    166         else return 3;
    167     }
    168     //点在线段上的判断
    169     bool pointonseg(Point p){
    170         return sgn((p-s)^(e-s))==0&&sgn((p-s)*(p-e))<=0;
    171     }
    172     //两向量平行(对应直线平行或重合)
    173     bool parallel(Line v){
    174         return sgn((e-s)^(v.e-v.s))==0;
    175     }
    176     //两线段相交判断
    177     //2 规范相交
    178     //1 非规范相交
    179     //0 不相交
    180     int segcrossseg(Line v){
    181         int d1=sgn((e-s)^(v.s-s));
    182         int d2=sgn((e-s)^(v.e-s));
    183         int d3=sgn((v.e-v.s)^(s-v.s));
    184         int d4=sgn((v.e-v.s)^(e-v.s));
    185         if((d1^d2)==-2&&(d3^d4)==-2) return 2;
    186         return (d1==0&&sgn((v.s-s)*(v.s-e))<=0||
    187                 d2==0&&sgn((v.e-s)*(v.e-e))<=0||
    188                 d3==0&&sgn((s-v.s)*(s-v.e))<=0||
    189                 d4==0&&sgn((e-v.s)*(e-v.e))<=0);
    190     }
    191     //直线和线段相交判断
    192     //-*this line -v seg
    193     //2 规范相交
    194     //1 非规范相交
    195     //0 不相交
    196     int linecrossseg(Line v){
    197         int d1=sgn((e-s)^(v.s-s));
    198         int d2=sgn((e-s)^(v.e-s));
    199         if((d1^d2)==-2) return 2;
    200         return (d1==0||d2==0);
    201     }
    202     //两直线关系
    203     //0 平行
    204     //1 重合
    205     //2 相交
    206     int linecrossline(Line v){
    207         if((*this).parallel(v))
    208             return v.relation(s)==3;
    209         return 2;
    210     }
    211     //求两直线的交点
    212     //要保证两直线不平行或重合
    213     Point crosspoint(Line v){
    214         double a1=(v.e-v.s)^(s-v.s);
    215         double a2=(v.e-v.s)^(e-v.s);
    216         return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
    217     }
    218     //点到直线的距离
    219     double dispointtoline(Point p){
    220         return fabs((p-s)^(e-s))/length();
    221     }
    222     //点到线段的距离
    223     double dispointtoseg(Point p){
    224         if(sgn((p-s)*(e-s))<0||sgn((p-e)*(s-e))<0)
    225             return min(p.distance(s),p.distance(e));
    226         return dispointtoline(p);
    227     }
    228     //返回线段到线段的距离
    229     //前提是两线段不相交,相交距离就是0了
    230     double dissegtoseg(Line v){
    231         return min(min(dispointtoseg(v.s),dispointtoseg(v.e)),min(v.dispointtoseg(s),v.dispointtoseg(e)));
    232     }
    233     //返回点P在直线上的投影
    234     Point lineprog(Point p){
    235         return s+(((e-s)*((e-s)*(p-s)))/((e-s).len2()));
    236     }
    237     //返回点P关于直线的对称点
    238     Point symmetrypoint(Point p){
    239         Point q=lineprog(p);
    240         return Point(2*q.x-p.x,2*q.y-p.y);
    241     }
    242 };
    243 
    244 Line L[1005];
    245 int n;
    246 
    247 bool Check(Line a,Line b){
    248     if(sgn((a.s-a.e)^(b.s-a.e))*sgn((a.s-a.e)^(b.e-a.e))>0) return false;
    249     if(sgn((b.s-b.e)^(a.s-b.e))*sgn((b.s-b.e)^(a.e-b.e))>0) return false;
    250     if(sgn(max(a.s.x,a.e.x)-min(b.s.x,b.e.x))>=0&&sgn(max(b.s.x,b.e.x)-min(a.s.x,a.e.x))>=0
    251      &&sgn(max(a.s.y,a.e.y)-min(b.s.y,b.e.y))>=0&&sgn(max(b.s.y,b.e.y)-min(a.s.y,a.e.y))>=0)
    252         return true;
    253     else return false;
    254 }
    255 
    256 
    257 double mp[115][115];
    258 
    259 int co;
    260 
    261 int panduan(Line a){
    262     int sum=0;
    263     for(int i=1;i<=n;i++){
    264         if(Check(a,L[i])){
    265             sum++;
    266         }
    267     }
    268     return sum;
    269 }
    270 
    271 int main(){
    272 
    273     while(~scanf("%d",&n)){
    274         for(int i=1;i<=n;i++){
    275             scanf("%lf %lf %lf %lf",&L[i].s.x,&L[i].s.y,&L[i].e.x,&L[i].e.y);
    276         }
    277         int ans=0x3f3f3f3f;
    278         Point goal;
    279         scanf("%lf %lf",&goal.x,&goal.y);
    280         Line tmp;
    281         tmp.s=goal;
    282         for(double i=0;i+eps<=100;i+=0.5){
    283             tmp.e.x=0,tmp.e.y=i;
    284             ans=min(ans,panduan(tmp));
    285             tmp.e.x=i,tmp.e.y=0;
    286             ans=min(ans,panduan(tmp));
    287             tmp.e.x=100,tmp.e.y=i;
    288             ans=min(ans,panduan(tmp));
    289             tmp.e.x=i,tmp.e.y=100;
    290             ans=min(ans,panduan(tmp));
    291         }
    292         printf("Number of doors = %d
    ",ans+1);
    293     }
    294 
    295     return 0;
    296 }
    View Code
  • 相关阅读:
    if语法案例
    其他6-break,continue,exit,return区别
    其他5-6种产生随机数的方法
    其他4-shell脚本后台运行知识
    算法练习 第三周
    回顾MySQL基础
    jsp中使用jQuery获取窗口高度不正确的问题
    初学java 学生管理系统——v04版本 改用web
    web项目中跳转路径的使用
    tomcat部署项目的方式
  • 原文地址:https://www.cnblogs.com/Fighting-sh/p/9928038.html
Copyright © 2011-2022 走看看