【poj3608】 Bridge Across Islands
来源:互联网 发布:红杉网络 编辑:程序博客网 时间:2024/06/05 02:27
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 16polygon 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;}
0 0
- POJ3608-Bridge Across Islands
- 【poj3608】 Bridge Across Islands
- poj3608 Bridge Across Islands
- poj3608 Bridge Across Islands (旋转卡壳之两凸包最短距)
- Bridge Across Islands POJ
- poj 3608 Bridge Across Islands
- 【POJ 3608】Bridge Across Islands
- POJ 3608 Bridge Across Islands
- POJ 3608 Bridge Across Islands
- poj 3608 Bridge Across Islands 凸包最短距离
- POJ 3608 Bridge Across Islands(旋转卡壳)
- POJ 3608 Bridge Across Islands 已翻译
- POJ:3608 Bridge Across Islands 旋转卡壳
- PKU 3608 Bridge Across Islands 凸包+旋转卡壳
- Bridge Across Islands----POJ_3608----求两凸包最近距离----旋转卡壳
- poj 3608 Bridge Across Islands(旋转卡壳)
- poj 3608 Bridge Across Islands(两凸包最近距离)
- POJ 3608 Bridge Across Islands (计算几何+三分)
- 锁屏状态下弹出对话款,类似QQ、微信锁屏时候屏幕小窗口显示消息
- Android自定义控件之日历控件
- 微盘链接信息
- <s:textfield></s:textfield>,<s:date>,<s:property>获取值
- ZabbixServer配置文件详解
- 【poj3608】 Bridge Across Islands
- Java多线程编程——对象及变量的并发访问 02
- 平衡二叉树
- [Java]1.运算符、流程控制、数组
- xcode下载
- popupwindow进入和退出动画
- 分布式集群运营管理系统-项目简介
- JavaScript验证码
- 优秀博客