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

题目大意:有n条线段 他们都在这个房间里   最后有一个点代表起始位置

现在想通过墙出去  他只能爆破每个房间的中点的门   问最少的门通过的

分析:   刚开始就想到暴力写   但是一想好麻烦   头都大了   最后还是暴力   我把边存错了 调试了好久  就过了

先找到每条线段(包括边界)与所有的线段之间的交点求出来   然后从左往右排下序  把中点存到一个结构体里(把边界的点特殊处理一下)

处理所有的中点   能直接相连的就置成1  否则就是INF     最后地杰斯特拉跑一边   把边缘的点比较一下就好

用G++ 交   c++的话  就把fabs改成abs就好  反正它本身就是整形

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include<math.h>
#include<queue>
#include<algorithm>
#include<iostream> using namespace std;
#define N 2000
const double ESP = 1e-;
#define INF 0x3f3f3f3f
#define memset(a,b) memset(a,b,sizeof(a)) int n; struct Point
{
double x,y;
int step;
Point (double x=,double y=):x(x),y(y) {} Point operator - (const Point &temp)const
{
return Point(x-temp.x,y-temp.y);
}
int operator * (const Point &temp)const
{
double t=(x*temp.y-y*temp.x);
if(t>ESP)
return ;
if(fabs(t)<ESP)
return ;
return -;
}
}; struct node
{
Point A,B;
node (Point A=,Point B=):A(A),B(B) {} }; Point p[N],d[N];
node a[N]; Point line(Point u1,Point u2,Point v1,Point v2)///求交点
{
Point ret=u1;
double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x)); ret.x+=(u2.x-u1.x)*t;
ret.y+=(u2.y-u1.y)*t; return ret;
} int cmp(const void *aa,const void *bb)
{
struct Point *cc,*dd;
cc=(struct Point *)aa;
dd=(struct Point *)bb;
if(cc->x!=dd->x)
return cc->x-dd->x;
else
return cc->y-dd->y;
} int G[N][N]; void serch(int o)
{
for(int i=;i<=o;i++)
{
for(int j=;j<=o;j++)
{
if(i==j)
continue;
int flag=;
for(int k=;k<n;k++)
{
int k1=fabs((d[i]-a[k].A)*(a[k].B-a[k].A)+(d[j]-a[k].A)*(a[k].B-a[k].A));
int k2=fabs((a[k].A-d[j])*(d[i]-d[j])+(a[k].B-d[j])*(d[i]-d[j]));
if(k1== && k2==)
{
flag=;
break;
}
}
if(flag==)
G[i][j]=;
}
}
} int vis[N],dis[N]; void dji(int s,int o)
{
memset(vis,);
for(int i=;i<=o;i++)
dis[i]=G[s][i];
for(int i=;i<=o;i++)
{
int Min=INF,dist;
for(int j=;j<=o;j++)
{
if(!vis[j] && Min>dis[j])
{
Min=dis[j];
dist=j;
}
}
vis[dist]=;
for(int j=;j<=o;j++)
{
dis[j]=min(dis[j],dis[dist]+G[dist][j]);
}
}
} int main()
{ double x1,x2,y1,y2;
while(scanf("%d",&n)!=EOF)
{ double x,y;
for(int i=; i<=n; i++)
{
scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
a[i]=node(Point(x1,y1),Point(x2,y2));
}
n=n+;
a[n++]=node(Point(,),Point(,));
a[n++]=node(Point(,),Point(,));
a[n++]=node(Point(,),Point(,));
a[n++]=node(Point(,),Point(,)); scanf("%lf %lf",&x,&y);
int o=;///中点的个数
int h[N];///在边缘的点
int aa=;///边缘点的个数
for(int i=; i<n; i++)
{
memset(p,);
int b=;
for(int j=; j<n; j++)
{
if(i==j)
continue;
int k=fabs((a[i].B-a[j].A)*(a[j].B-a[j].A)+(a[i].A-a[j].A)*(a[j].B-a[j].A));
int kk=fabs((a[j].B-a[i].A)*(a[i].B-a[i].A)+(a[j].A-a[i].A)*(a[i].B-a[i].A));
if(k!= && kk!=)///如果两个线段相交 求交点
{
p[b++]=line(a[i].A,a[i].B,a[j].A,a[j].B);
}
}
qsort(p,b,sizeof(p[]),cmp);///交点从左向右排序 for(int j=;j<b;j++)///每一条线段的中点
{
d[o]=Point((p[j].x+p[j-].x)/2.0,(p[j].y+p[j-].y)/2.0);
if(d[o].x== || d[o].x== || d[o].y== || d[o].y==)///边界点
{
h[aa++]=o;
}
o++;
}
}
d[o]=Point(x,y);///起始点
for(int i=;i<=o;i++)
{
for(int j=;j<=o;j++)
G[i][j]=INF;
}
serch(o);///判断这两个中点是否能直接相连
dji(o,o);///最短路
int Min=INF;
for(int i=;i<aa;i++)
{
Min=min(Min,dis[h[i]]);
}
printf("Number of doors = %d \n",Min);
}
return ;
}

Treasure Hunt--poj1066(最短路加判断线段的关系)的更多相关文章

  1. Revit API判断直线相交关系移动风管

    start )             );         )) )) );         XYZ xyz12 = lCurve1.Curve.get_EndPoint();         XY ...

  2. POJ 1066 Treasure Hunt(线段相交判断)

    Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4797   Accepted: 1998 Des ...

  3. POJ 1066 - Treasure Hunt - [枚举+判断线段相交]

    题目链接:http://poj.org/problem?id=1066 Time Limit: 1000MS Memory Limit: 10000K Description Archeologist ...

  4. POJ 1066 Treasure Hunt(相交线段&amp;&amp;更改)

    Treasure Hunt 大意:在一个矩形区域内.有n条线段,线段的端点是在矩形边上的,有一个特殊点,问从这个点到矩形边的最少经过的线段条数最少的书目,穿越仅仅能在中点穿越. 思路:须要巧妙的转换一 ...

  5. poj1066 Treasure Hunt【计算几何】

    Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8192   Accepted: 3376 Des ...

  6. POJ 1066--Treasure Hunt(判断线段相交)

    Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7857   Accepted: 3247 Des ...

  7. POJ_1556_The Doors_判断线段相交+最短路

    POJ_1556_The Doors_判断线段相交+最短路 Description You are to find the length of the shortest path through a ...

  8. POJ 2556 (判断线段相交 + 最短路)

    题目: 传送门 题意:在一个左小角坐标为(0, 0),右上角坐标为(10, 10)的房间里,有 n 堵墙,每堵墙都有两个门.每堵墙的输入方式为 x, y1, y2, y3, y4,x 是墙的横坐标,第 ...

  9. 简单几何(线段相交) POJ 1066 Treasure Hunt

    题目传送门 题意:从四面任意点出发,有若干障碍门,问最少要轰掉几扇门才能到达终点 分析:枚举入口点,也就是线段的两个端点,然后选取与其他线段相交点数最少的 + 1就是答案.特判一下n == 0的时候 ...

随机推荐

  1. asp.net mvc 5 微信接入VB版 - 获取AccessToken

    获取AccessToken是微信接入的又一个基础操作.很多微信接口需要这个2小时一刷新的AccessToken作为参数. 转载请说明作者Nukepayload2 首先根据开发文档把获取AccessTo ...

  2. centos7 设置grub密码及单用户登录实例

    centos7与centos6在设置grub密码的操作步骤上有很大的差别,特此记录供以后查用 grub加密的目的: 防止不法分子利用单用户模式修改root密码 给grub加密可以采用明文或者加密的密文 ...

  3. docker环境安装

    centos7安装docker环境 # step 1: 安装必要的一些系统工具 yum install -y yum-utils device-mapper-persistent-data lvm2 ...

  4. 基础数据类型(set集合)

    认识集合 由一个或多个确定的元素所构成的整体叫做集合. 集合中的元素有三个特征: 1.确定性(集合中的元素必须是确定的) 2.互异性(集合中的元素互不相同.例如:集合A={1,a},则a不能等于1) ...

  5. python爬虫---从零开始(三)Requests库

    1,什么是Requests库 Requests是用python语言编写,基于urllib,采用Apache2 Licensed 开源协议的HTTP库. 它比urllib更加方便,可以节约我们大量的工作 ...

  6. 在虚拟机linux环境下编译windows版adb fastboot

    原文出自:http://blog.chinaunix.net/uid-20546441-id-1746200.html 我根据虚拟机编译遇到的问题进行一些添加 [前提条件] Linux Android ...

  7. PHP将数据库的数据转换成json格式

    header('content-type:application/json;charset=utf8');  $results = array();     while ($row = mysql_f ...

  8. 深入Linux内核架构——进程管理和调度(上)

    如果系统只有一个处理器,那么给定时刻只有一个程序可以运行.在多处理器系统中,真正并行运行的进程数目取决于物理CPU的数目.内核和处理器建立了多任务的错觉,是通过以很短的间隔在系统运行的应用程序之间不停 ...

  9. tornado框架基础08-sqlalchemy表关系和简单登录注册

    01 一对一表关系 Module 需要先创建对应的 Module ,这里采用之前建立好的 User 和 UserDetails relationship from sqlalchemy.orm imp ...

  10. Android开发——查询/杀死手机里正在运行的进程

    0. 前言 以前有同学好像做过一个叫"自习君"的App,开启后自动检测用户这一天的自习时间,在学校里宣传广告还打了不少.其实实现原理非常简单,在SQlite数据库(也可以通过文件) ...