【poj3608】 Bridge Across Islands
http://poj.org/problem?id=3608 (题目链接)
题意
求两凸包间最短距离
Solution
难写难调,旋转卡壳,还真是卡死我了。
先分别选出两凸包最上点和最下点,从这两点开始向逆时针方向旋转卡壳。用叉乘判断是否旋转旋转,具体操作跟求凸包直径差不多。
poj discuss蒯下来的数据制造器:
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std; struct point{double x,y;};
struct polygon
{
int n;
point data[10];
};
#define N 16
polygon p[N]={
{4,{{0,0},{-1,0},{-1,-1},{0,-1}}},
{4,{{2,0},{2,-1},{3,-1},{3,0}}},
{4,{{247,208},{247,235},{375,235},{375,208}}},
{3,{{85 ,101},{116 ,168},{168 ,103}}},
{3,{{131 ,189},{216 ,148},{196 ,209}}},
{3,{{180 ,127},{246 ,127},{202 ,144}}},
{3,{{226 ,201},{297 ,201},{242 ,151}}},
{3,{{42 ,225},{61 ,261},{100,222}}},
{3,{{84 ,261},{99 ,246},{102,260}}},
{3,{{72,309},{157,224},{167,309}}},
{3,{{170,221},{229,221},{199,245}}},
{3,{{190,90},{153,47},{225,108}}},
{3,{{165,230},{168,242},{172,233}}},
{6,{{143,146},{133,156},{138,170},{150,173},{161,166},{161,152}}},
{5,{{109,208},{100,236},{111,253},{122,250},{161,206}}},
{6,{{177,273},{174,309},{202,377},{417,375},{490,270},{268,239}}}
};
int main()
{
srand(time(NULL));
//freopen("aaa.in","w",stdout);
int i=0,j=0,k,num=0;
while (i==j) i=rand()%N,j=rand()%N;
num++;
//if(num>35||num<=33)continue;
printf("%d %d\n",p[i].n,p[j].n);
for(k=0;k<p[i].n;k++)
printf("%lf %lf\n",p[i].data[k].x,p[i].data[k].y);
for(k=0;k<p[j].n;k++)
printf("%lf %lf\n",p[j].data[k].x,p[j].data[k].y);
printf("0 0\n");
return 0;
}
代码
// poj3608
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<map>
#define esp 1e-8
#define inf 2147483640
#define LL long long
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
using namespace std;
inline LL getint() {
LL x=0,f=1;char ch=getchar();
while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*f;
} const int maxn=10010;
struct point {
double x,y;
point() {};
point (double _x,double _y):x(_x),y(_y){}
friend point operator - (const point &a,const point &b) {
point x;
x.x=a.x-b.x;x.y=a.y-b.y;
return x;
}
}p1[maxn],p2[maxn],p0;
int sn[maxn],sm[maxn],n,m; double cross(point p0,point p1,point p2) { //叉乘
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double dis(point a,point b) { //点a与点b之间的距离
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool cmp(point a,point b) { //极角排序
double t=cross(p0,a,b);
if (t<0) return 0;
if (t>0) return 1;
return dis(p0,a)<dis(p0,b);
}
int dcmp(double x) { //double比较
return fabs(x)<esp ? 0 : (x>0 ? 1 : -1);
}
int Graham(int n,point *p) { //求凸包
int k=1,top=2;
for (int i=2;i<=n;i++)
if (p[i].x==p[k].x ? p[i].y<p[k].y : p[i].x<p[k].x) k=i;
p0=p[k];p[k]=p[1];p[1]=p0;
sort(p+2,p+1+n,cmp);
for (int i=3;i<=n;i++) {
while (top>1 && cross(p[top-1],p[top],p[i])<=0) top--;
p[++top]=p[i];
}
return top;
}
double pldis(point a,point b,point c) { //点a到线段bc的最短距离
point s(a-b),t(c-b);
if (s.x*t.x+s.y*t.y<0) return dis(a,b);
s=(a-c);t=(b-c);
if (s.x*t.x+s.y*t.y<0) return dis(a,c);
return fabs(cross(a,b,c))/dis(b,c);
}
double lldis(point a,point b,point c,point d) { //线段ab与线段cd的最短距离
return min(min(pldis(a,c,d),pldis(b,c,d)),min(pldis(c,a,b),pldis(d,a,b)));
}
double RC(point *pl,point *pr,int p,int q,int n,int m) { //旋转卡壳
double tmp,minl=1e90;
pl[n+1]=pl[1];pr[m+1]=pr[1];
for (int i=1;i<=n;i++) {
while ((tmp=cross(pl[p+1],pr[q+1],pl[p])-cross(pl[p+1],pr[q],pl[p]))>esp) q=q%m+1;
if (tmp<-esp) minl=min(minl,pldis(pr[q],pl[p],pl[p+1]));
else minl=min(minl,lldis(pl[p],pl[p+1],pr[q],pr[q+1]));
p=p%n+1;
}
return minl;
}
void clocksort() { //逆时针排序
p0.x=0;p0.y=0;
for (int i=1;i<=n;i++) {p0.x+=p1[i].x;p0.y+=p1[i].y;}
p0.x/=n;p0.y/=n;
sort(p1+1,p1+1+n,cmp);
p0.x=0;p0.y=0;
for (int i=1;i<=m;i++) {p0.x+=p2[i].x;p0.y+=p2[i].y;}
p0.x/=m;p0.y/=m;
sort(p2+1,p2+1+m,cmp);
}
int main() {
while (scanf("%d%d",&n,&m)!=EOF && n && m) {
for (int i=1;i<=n;i++) scanf("%lf%lf",&p1[i].x,&p1[i].y);
for (int i=1;i<=m;i++) scanf("%lf%lf",&p2[i].x,&p2[i].y);
n=Graham(n,p1);
m=Graham(m,p2);
//clocksort();
int l=1,r=1;
for (int i=1;i<=n;i++) if (dcmp(p1[i].y-p1[l].y)<0) l=i; //最下点
for (int i=1;i<=m;i++) if (dcmp(p2[i].y-p2[r].y)>0) r=i; //最上点
printf("%.5lf\n",min(RC(p1,p2,l,r,n,m),RC(p2,p1,r,l,m,n)));
}
return 0;
}
【poj3608】 Bridge Across Islands的更多相关文章
- 【设计模式】Bridge模式(桥接模式)
最近的一次面试中,被问到桥接模式,以前呢并没有很仔细的研究过这个设计模式,借此机会剖析一下. 先给出自己对这个模式理解后的源码: interface A{ void methodA(); } inte ...
- 「POJ-3608」Bridge Across Islands (旋转卡壳--求两凸包距离)
题目链接 POJ-3608 Bridge Across Islands 题意 依次按逆时针方向给出凸包,在两个凸包小岛之间造桥,求最小距离. 题解 旋转卡壳的应用之一:求两凸包的最近距离. 找到凸包 ...
- 【BZOJ-2095】Bridge 最大流 + 混合图欧拉回路 + 二分
2095: [Poi2010]Bridges Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 604 Solved: 218[Submit][Stat ...
- 【leetcode】Number of Islands(middle)
Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...
- 【LeetCode】Number of Islands
Number of Islands 问题描写叙述 Given a 2d grid map of '1's (land) and '0's (water), count the number of is ...
- 【设计模式】Bridge
前言 Bridge设计模式,将一个复杂类分成可以单独开发的部分.分成的两个部分,abstraction,implementation.字面上是抽象和实现,但不同于抽象方法及其实现.下面摘录Wiki的两 ...
- 【BZOJ2095】 Bridge
Time Limit: 1000 ms Memory Limit: 128 MB Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个 ...
- 【BZOJ2095】【POI2010】Bridge 网络流
题目大意 给你一个无向图,每条边的两个方向的边权可能不同.要求找出一条欧拉回路使得路径上的边权的最大值最小.无解输出"NIE". \(2\leq n\leq 1000,1\le ...
- 【LA3485】 Bridge
前言 哈哈哈,垃圾微积分哈哈哈 前置知识:自适应Simpson法与微积分初步,学会编程 Solution 考虑一下我们有的是什么: 一段桥梁的横向距离,悬线的长度,以及高度. 我们发现如果我们重新设一 ...
随机推荐
- c#中结构体(struct)和类(class)的区别
一.类与结构的示例比较: 结构示例: public struct Person { string Name; int height; int weight public bool overWeight ...
- 监控Mysql主从环境下Slave延迟状态的操作记录
在MySQL主从环境下,通常会根据Seconds_Behind_Master的值来判断slave的延迟状态,这么做在大部分情况下尚可接受,但其实是并不够准确的.对于Slave延迟状态的监控,应该考虑多 ...
- HYSBZ 2145 悄悄话
2145: 悄悄话 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 271 Solved: 104[Submit][Status][Discuss] ...
- CSS选择器的权重与优先规则
权重顺序 “important > 内联 > ID > 类 > 标签 | 伪类 | 属性选择 > 伪对象 > 继承 > 通配符”. 原文:http://w ...
- CSS规则的执行顺序(转)
你对CSS规则的执行顺序是否了解,这里和大家分享一下,若两条规则具有相同的权值.起源及特殊性,那在样式表中最后出现的规则优先. 1.CSS规则之特殊性 首先来看一下这个例子将会发生的情形: <s ...
- usb驱动开发4之总线设备驱动模型
在上文说usb_init函数,却给我们留下了很多岔路口.这次就来好好聊聊关于总线设备驱动模型.这节只讲理论,不讲其中的函数方法,关于函数方法使用参考其他资料. 总线.设备.驱动对应内核结构体分别为bu ...
- 待整理-coredump
Linux下如何产生coredump(gdb调试用) 任务发生异常,需要记录遗言信息,利用gdb调试,因此需要记录coredump文件.设置查看:在root用户下执行sysctl -a | grep ...
- iOS 定位精度
时间 2015-03-19 18:30:59 图灵社区 由于iOS不能直接控制到GPS,一般来说我们都会使用CLLocationManager来获取地理位置信息,我们会使用 manager.des ...
- jQuery.stickUp插件重构
stickUp插件用于实现固定菜单栏效果,原理很简单,说白了就是监听document的scroll事件,滚动到特定值时,将特定元素的position设置为fixed,核心代码如下: $(docum ...
- (旧)子数涵数·PS ——翻页效果
一.首先在网络上下载一张图片,作为素材.这是我下载的素材,至于为什么选择这张照片呢,当然不是因为自己的一些羞羞的念头啦. 二.打开Photoshop,我使用的版本是CS3(因为CS3所占的磁盘空间较小 ...