zoukankan      html  css  js  c++  java
  • Gym

    题目链接:

    http://acm.hust.edu.cn/vjudge/problem/307216

    Froggy Ford

    Time Limit: 3000MS

    题意

    青蛙过河,河中有若干个石头,现在你可以加一个石头,使得青蛙从左岸跳到右岸的最大跳跃距离最小。

    题解

    把左岸和右岸作为两个虚节点,用kruskal的思路处理出每个点到左岸需要跳跃的最大距离st[i](最优情况下)和每个点到右岸的最大距离ed[i],然后枚举两个点,在这两个点的中点放一个石头,得到ma=max(st[i],ed[j],dis(i,j)/2),如果这个值比答案更优,就更新答案,同时记录新放的石头的坐标。

    代码

    #include<map>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=9e18;
    const double eps=1e-8;
    
    const int maxn=1111;
    
    LL w,n;
    
    pair<LL,LL> pt[maxn];
    
    LL dis(LL x1,LL y1,LL x2,LL y2){
    	return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
    }
    
    struct Edge{
    	int u,v; 
    	LL w;
    	Edge(int u,int v,LL w):u(u),v(v),w(w){}
    	Edge(){}
    	bool operator < (const Edge& tmp) const {
    		return w<tmp.w;
    	}
    }egs[maxn*maxn];
    
    int tot;
    int fa[maxn];
    int find(int x){
    	return fa[x]=fa[x]==x?x:find(fa[x]);
    }
    
    vector<int> G[maxn];
    int st[maxn],ed[maxn];
    
    void init(){
    	clr(st,-1);
    	clr(ed,-1);
    	tot=0;
    	rep(i,0,maxn) fa[i]=i;
    	rep(i,0,maxn) G[i].push_back(i);
    }
    
    int main() {
    	freopen("froggy.in","r",stdin);
    	freopen("froggy.out","w",stdout);
    	
    	init();
    	
    	scanf("%I64d%I64d",&w,&n);
    	rep(i,1,n+1) scanf("%I64d%I64d",&pt[i].X,&pt[i].Y);
    	
    	rep(i,1,n+1){
    		egs[tot++]=Edge(0,i,pt[i].X*pt[i].X);
    	}
    	rep(i,1,n+1){
    		egs[tot++]=Edge(i,n+1,(w-pt[i].X)*(w-pt[i].X)); 
    	}
    	rep(i,1,n+1){
    		rep(j,i+1,n+1){
    			egs[tot++]=Edge(i,j,dis(pt[i].X,pt[i].Y,pt[j].X,pt[j].Y));
    		}
    	}
    	egs[tot++]=Edge(0,n+1,w*w);
    	egs[tot++]=Edge(0,0,0);
    	egs[tot++]=Edge(n+1,n+1,0);
    	sort(egs,egs+tot);
    	
    	rep(i,0,tot){
    		int u=egs[i].u,v=egs[i].v;
    		if(u==0&&v==0){
    			st[0]=i; continue;
    		}
    		if(u==n+1&&v==n+1){
    			ed[n+1]=i; continue;
    		}
    		int pu=find(u);
    		int pv=find(v);
    		if(pu!=pv){
    			if(find(0)==pu){
    				rep(j,0,G[pv].size()){
    					int tt=G[pv][j];
    					st[tt]=i;
    				}
    			}else if(find(0)==pv){
    				rep(j,0,G[pu].size()){
    					int tt=G[pu][j];
    					st[tt]=i;
    				}
    			}
    			if(find(n+1)==pu){
    				rep(j,0,G[pv].size()){
    					int tt=G[pv][j];
    					ed[tt]=i;
    				}
    			}else if(find(n+1)==pv){
    				rep(j,0,G[pu].size()){
    					int tt=G[pu][j];
    					ed[tt]=i;
    				}
    			}
    			fa[pv]=pu;
    			while(G[pv].size()>0){
    				G[pu].push_back(G[pv][G[pv].sz()-1]);
    				G[pv].pop_back();
    			}
    		}
    	}
    	
    	int ans_i=0,ans_j=0;
    	double mi=9000000000000000000;
    	rep(i,0,n+2){
    		rep(j,0,n+2){
    			if(i==j) continue;
    			double tmp=max(egs[st[i]].w,egs[ed[j]].w);
    			int ti=i,tj=j;
    			if(ti>tj) swap(ti,tj);
    			if(ti==0&&tj==n+1){
    				tmp=max(tmp,w*w*1.0/4);
    			}else if(ti==0){
    				tmp=max(tmp,pt[tj].X*pt[tj].X*1.0/4);
    			}else if(tj==n+1){
    				tmp=max(tmp,(w-pt[ti].X)*(w-pt[ti].X)*1.0/4);
    			}else{
    				tmp=max(tmp,dis(pt[i].X,pt[i].Y,pt[j].X,pt[j].Y)*1.0/4);
    			}
    			if(tmp<mi){
    				mi=tmp;
    				ans_i=i; ans_j=j;
    			}
    		}
    	}
    	
    	double ans_x=0,ans_y=0;
    	if(ans_i>ans_j) swap(ans_i,ans_j);
    	if(ans_i==0&&ans_j==n+1){
    		ans_x=w*1.0/2;
    		ans_y=0;
    	}else if(ans_i==0){
    		ans_x=pt[ans_j].X*1.0/2;
    		ans_y=pt[ans_j].Y;
    	}else if(ans_j==n+1){
    		ans_x=(w+pt[ans_i].X)*1.0/2;
    		ans_y=pt[ans_i].Y;
    	}else{
    		ans_x=(pt[ans_i].X+pt[ans_j].X)*1.0/2;
    		ans_y=(pt[ans_i].Y+pt[ans_j].Y)*1.0/2; 
    	}
    	
    	printf("%.3lf %.3lf
    ",ans_x,ans_y);
    	return 0;
    }
  • 相关阅读:
    移动端开发常遇问题解答
    CSS属性小结之--半透明处理
    jquery事件代理
    sprite图在移动端的使用
    vertical-align及IE7下的inline-block
    图片延迟加载
    iOS NSInteger/NSUInteger与int/unsigned int、long/unsigned long之间的区别!
    GCD深入理解(1)
    iOS 开发图片资源选择png格式还是jpg格式
    iOS沙盒(sandbox)机制及获取沙盒路径
  • 原文地址:https://www.cnblogs.com/fenice/p/5769356.html
Copyright © 2011-2022 走看看