链接

很纠结的找到了所有线段的中点,又很纠结的找到了哪些中点可以直接相连,最后bfs一下求出了最短路。。

 #include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 2210
#define LL long long
#define INF 0xfffffff
const double eps = 1e-;
const double inf = ~0u>>;
vector<int>ed[N];
struct Point
{
double x,y;
Point(double x=,double y=):x(x),y(y) {} //构造函数 方便代码编写
} p[],q[N];
int g,dis[N];
bool vis[N];
vector<Point>pi[N];
typedef Point pointt;
pointt operator + (Point a,Point b)
{
return Point(a.x+b.x,a.y+b.y);
}
pointt operator - (Point a,Point b)
{
return Point(a.x-b.x,a.y-b.y);
}
pointt operator * (Point a,double b)
{
return Point(a.x*b,a.y*b);
}
pointt operator / (Point a,double b)
{
return Point(a.x/b,a.y/b);
}
bool operator < (const Point &a,const Point &b)
{
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
int dcmp(double x)
{
if(fabs(x)<eps) return ;
else return x<?-:;
}
double cross(Point a,Point b)
{
return a.x*b.y-a.y*b.x;
}
Point intersection1(Point a,Point b,Point c,Point d)//直线交点求解
{
Point pp = a;
double t = ((a.x-c.x)*(c.y-d.y)-(a.y-c.y)*(c.x-d.x))/
((a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x));
pp.x+=(b.x-a.x)*t;
pp.y+=(b.y-a.y)*t;
return pp;
}
bool seginter(pointt a1,pointt a2,pointt b1,pointt b2)
{
double c1 = cross(a2-a1,b1-a1),c2 = cross(a2-a1,b2-a1),
c3 = cross(b2-b1,a1-b1),c4 = cross(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2)<&&dcmp(c3)*dcmp(c4)<;
}
void init(int i,int n)
{
p[i+].x = ;
p[i+].y = ;
p[i+].x = ;
p[i+].y = ;
p[i+].x = ;
p[i+].y = ;
p[i+].x = ;
p[i+].y = ;
p[i++n] = p[i+];
p[i++n] = p[i+];
p[i++n] = p[i+];
p[i++n] = p[i+]; }
int judge(int x)
{
if(fabs(q[x].x)<eps||fabs(q[x].y)<eps||fabs(q[x].x-100.0)<eps||fabs(q[x].y-100.0)<eps)
return ;
return ;
}
void bfs(int st)
{
queue<int>Q;
Q.push(st);
memset(vis,,sizeof(vis));
// cut<<
for(int i = ; i <= st ; i++)
dis[i] = INF;
dis[st] = ;
while(!Q.empty())
{
int u = Q.front();
Q.pop();
//printf("%.2f %.2f %d\n",q[u].x,q[u].y,dis[u]);
if(judge(u))
{
printf("Number of doors = %d\n",dis[u]);
break;
}
for(int i = ; i < ed[u].size() ; i++)
{
int v = ed[u][i];
//cout<<v<<" "<<dis[u]<<endl;
dis[v] = min(dis[v],dis[u]+);
if(!vis[v])
{
vis[v] = ;
Q.push(v);
}
}
}
}
bool cmp(Point a,Point b)
{
if(fabs(a.x-b.x)<eps)
return a.y<b.y;
return a.x<b.x;
}
int main()
{
int n,i,j,e;
scanf("%d",&n);
// while(scanf("%d",&n)!=EOF)
// {
n+=;
g = ;
for(i = ; i <= n- ; i++)
{
scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i+n].x,&p[i+n].y);
}
init(n-,n);
for(i = ; i <= n-; i++)
{
for(j = ; j <= n- ; j++)
{
if(i==j) continue;
if(seginter(p[i],p[i+n],p[j],p[j+n]))
{
pi[i].push_back(intersection1(p[i],p[i+n],p[j],p[j+n]));
}
}
}
for(i = ; i <= n- ; i++)
{
if(dcmp(p[i].x)==)
pi[n-].push_back(p[i]);
if(dcmp(p[i+n].x)==)
pi[n-].push_back(p[i+n]);
if(dcmp(p[i].y-)==)
pi[n-].push_back(p[i]);
if(dcmp(p[i+n].y-)==)
pi[n-].push_back(p[i+n]);
if(dcmp(p[i].x-)==)
pi[n-].push_back(p[i]);
if(dcmp(p[i+n].x-)==)
pi[n-].push_back(p[i+n]);
if(dcmp(p[i].y)==)
pi[n].push_back(p[i]);
if(dcmp(p[i+n].y)==)
pi[n].push_back(p[i+n]);
}
for(i = ; i <= n; i++)
{
pi[i].push_back(p[i]);
pi[i].push_back(p[i+n]);
sort(pi[i].begin(),pi[i].end(),cmp);
for(j = ; j < pi[i].size()- ; j++)
{
Point tp;
Point p1 = pi[i][j],p2= pi[i][j+];
if(dcmp(p1.x-p2.x)==&&dcmp(p1.y-p2.y)==) continue;
tp.x = (p1.x+p2.x)/;
tp.y = (p1.y+p2.y)/;
// printf("%d tpx = %.2f tpy = %.2f p1x = %.2f p1y = %.2f p2x = %.2f p2y = %.2f\n",i,tp.x,tp.y,p1.x,p1.y,p2.x,p2.y);
q[++g] = tp;
}
pi[i].clear();
}
g++;
scanf("%lf%lf",&q[g].x,&q[g].y);
for(i = ; i <= g ; i++)
ed[i].clear();
for(i = ; i <= g ; i++)
{
// printf("%.2f %.2f\n",q[i].x,q[i].y);
for(j = ; j <= g ; j++)
{
if(i==j) continue;
for(e = ; e <= n; e++)
{
if(seginter(q[i],q[j],p[e],p[e+n]))
{
// if(i==g)
// printf("%.2f %.2f e = %d\n",q[j].x,q[j].y,e);
break;
}
}
if(e>n)
{
// if(i==g)
// printf("%.2f %.2f %.2f %.2f\n",q[i].x,q[i].y,q[j].x,q[j].y);
ed[i].push_back(j);
}
}
}
bfs(g);
// }
return ;
}

感觉这题没那么复杂,交对后搜了下题解,,然后 这题是一个水题,确实水。。

因为这个点的最终目的是要走出去的,边界上墙的点相对于边界上其它的点应该是更优的,所以只需枚举这些点到达起点经过多少堵墙即可。

几何抓不住重点是件很纠结的事。

附优美的简短的跑得飞快的代码

 #include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 2210
#define LL long long
#define INF 0xfffffff
const double eps = 1e-;
const double inf = ~0u>>;
vector<int>ed[N];
struct Point
{
double x,y;
Point(double x=,double y=):x(x),y(y) {} //构造函数 方便代码编写
} p[],q[N];
int g,dis[N];
bool vis[N];
vector<Point>pi[N];
typedef Point pointt;
pointt operator + (Point a,Point b)
{
return Point(a.x+b.x,a.y+b.y);
}
pointt operator - (Point a,Point b)
{
return Point(a.x-b.x,a.y-b.y);
}
pointt operator * (Point a,double b)
{
return Point(a.x*b,a.y*b);
}
pointt operator / (Point a,double b)
{
return Point(a.x/b,a.y/b);
}
bool operator < (const Point &a,const Point &b)
{
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
int dcmp(double x)
{
if(fabs(x)<eps) return ;
else return x<?-:;
}
double cross(Point a,Point b)
{
return a.x*b.y-a.y*b.x;
}
bool seginter(pointt a1,pointt a2,pointt b1,pointt b2)
{
double c1 = cross(a2-a1,b1-a1),c2 = cross(a2-a1,b2-a1),
c3 = cross(b2-b1,a1-b1),c4 = cross(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2)<&&dcmp(c3)*dcmp(c4)<;
}
int main()
{
int n,i,j,e;
scanf("%d",&n);
g = ;
for(i = ; i <= n ; i++)
{
scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i+n].x,&p[i+n].y);
}
Point tp;
scanf("%lf%lf",&tp.x,&tp.y);
if(n==)
{
puts("Number of doors = 1");
return ;
}
int ans = INF;
for(i = ; i <= n*; i++)
{
int ts = ;
for(j = ; j <= n ; j++)
{
if(seginter(p[i],tp,p[j],p[j+n]))
ts++;
}
ans = min(ans,ts);
}
printf("Number of doors = %d\n",ans);
return ;
}

poj1066Treasure Hunt(线段相交)的更多相关文章

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

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

  2. poj 1066 Treasure Hunt 线段相交

    题目链接 题目描述 一个正方形房间被分成若干个小室,宝藏在其中某一点.现可炸开任意一堵墙壁的中点位置.问至少要炸开多少堵墙才能从外面到达宝藏所在地. 思路 (很巧妙,没想到) 直接枚举墙壁与正方形外壁 ...

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

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

  4. POJ 1066 Treasure Hunt (线段相交)

    题意:给你一个100*100的正方形,再给你n条线(墙),保证线段一定在正方形内且端点在正方形边界(外墙),最后给你一个正方形内的点(保证不再墙上) 告诉你墙之间(包括外墙)围成了一些小房间,在小房间 ...

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

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

  6. poj 1066 线段相交

    链接:http://poj.org/problem?id=1066 Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Subm ...

  7. poj 1066(枚举+线段相交)

    Treasure Hunt Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6328   Accepted: 2627 Des ...

  8. POJ 2653 Pick-up sticks (线段相交)

    题意:给你n条线段依次放到二维平面上,问最后有哪些没与前面的线段相交,即它是顶上的线段 题解:数据弱,正向纯模拟可过 但是有一个陷阱:如果我们从后面向前枚举,找与前面哪些相交,再删除前面那些相交的线段 ...

  9. HDU1086You can Solve a Geometry Problem too(判断线段相交)

    You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/3 ...

  10. POJ 2653 Pick-up sticks【线段相交】

    题意:n根木棍随意摆放在一个平面上,问放在最上面的木棍是哪些. 思路:线段相交,因为题目说最多有1000根在最上面.所以从后往前处理,直到木棍没了或者最上面的木棍的总数大于1000. #include ...

随机推荐

  1. HDU 2236:无题II(二分搜索+二分匹配)

    http://acm.hdu.edu.cn/showproblem.php?pid=2236 题意:中文题意. 思路:先找出最大和最小值,然后二分差值,对于每一个差值从下界开始枚举判断能不能二分匹配. ...

  2. uname -r和uname -a了解

    1.uname -r :显示操作系统的发行版号2.uname -a :显示系统名.节点名称.操作系统的发行版号.操作系统版本.运行系统的机器 ID 号. #uname -aHP-UX RX1600 B ...

  3. python:正则表达式 re

    #re正则的用法:match匹配从开头 search 取一个就回来了,findout取所以匹配的,slit分割 sub替换 #-*- coding:utf8 -*- # Auth:fulimei #r ...

  4. linux socket高性能服务器处理框架

    这个博客很多东西 http://blog.csdn.net/luozhonghua2014/article/details/37041765   思考一种高性能的服务器处理框架 1.首先需要一个内存池 ...

  5. JAVA fundamentals of exception handling mechanism

    Agenda Three Categories Of Exceptions Exceptions Hierarchy try-catch-finally block The try-with-reso ...

  6. 对“Java”的诞生历史、特点、定义等HR常问的简单题

    本人是一个学习Java的新手,在学习了Java以后,对Java的一些总结. 这里共有12点对Java的简单的阐述,如果解释的不怎么样请大家谅解哈. 1.首先我们来看一看,在Java之前的有那些打牌语言 ...

  7. Educational Codeforces Round 1 A

    In this problem you are to calculate the sum of all integers from 1 to n, but you should take all po ...

  8. [转]Windows8下设置VS默认启动方式为管理员启动

    在Windows7下通常使用修改属性的方式:在任意快捷方式上右击,选择属性,选择高级,选择以管理员身份启动: 在Windows8下如上设置后,右击直接打开项目的话是不会以管理员身份启动的,这里用比较h ...

  9. Linux内核中的Kconfig、xx.defconfig、xx.config、Makefile

    什么是Kconfig.xx.defconfig.xx.config.Makefile Kconfig: 一个文本形式的文件,其中主要作用是在内核配置时候,作为配置选项. xx.deconfig: Li ...

  10. C语言第2天基本运算

    getchar 一.首先给出<The_C_Programming_Language>这本书中的例子: #include <stdio.h> int main( ) {      ...