hdu 4036 暴力二分 高精度 Rolling Hongshu

题意:http://acm.hdu.edu.cn/showproblem.php?pid=4036

       神一般的二分。一个sweet potato想要去约会,从起点滚到终点,途经一个mountain,有m个峰顶,第一个峰顶,第m个峰顶分别为起点和终点,忽略摩擦力,在每一个斜坡上分布着bitter potatoes,每经过一个bitter potato,bitter potato就会以一定的初速度追赶sweet potato,问,sweet potato应该以最小多大的初速度滚动,保证不被bitter potato追到,完成约会;

解:

    不仅要考虑到苦patato的时候速度要大,而且要考虑过山峰的时候速度要大于等于0.因为这个wa了甚久。然后全删了,本来还以为是我以前写过,于是就把以前代码贴过来改。改。但是事实是那是昨天朱老板用我的账号交的。。。不管怎样,题意以及解法是懂了的。

   还有,尽量少开方

   网上还有代码是直接求的,不二分。求出到每个山峰需要多少速度,求出不被苦potato追到需要多少速度,取最大的。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#define eps 1.0e-8
using namespace std;

struct node{
    double x,y,w,v;
    bool flag;
}point[5555];

struct line{
    double k,b;
};

line getl(node a,node b){
    line ans;
    ans.k = (b.y - a.y)/(b.x - a.x);
    ans.b = a.y - a.x*ans.k;
    return ans;
}

bool cmp(node a,node b){
    if(a.x != b.x)
        return a.x < b.x;
    return a.y < b.y;
}
int main(){
    int T,n,m,w;
    scanf("%d",&T);
    int id = 1;
    double g = 20.0;
    while(T--){
        scanf("%d%d%d",&n,&m,&w);
        for(int i = 0 ; i < n ; i ++){
            scanf("%lf%lf",&point[i].x,&point[i].y);
            point[i].flag = 0;
        }
        for(int i = n ; i < n + m ; i ++){
            point[i].y = -1000000000;
            scanf("%lf%lf%lf",&point[i].x,&point[i].v,&point[i].w);
            point[i].flag = 1;
        }
        sort(point,point+n+m,cmp);
        for(int i = 0 ; i < n + m ; i ++){
            if(point[i].flag == 1){
                int j = i;
                while(j--){
                    if(point[j].flag == 0)
                        break;
                }
                int k = i;
                while(k++){
                    if(point[k].flag == 0)
                        break;
                }
                line tp = getl(point[j],point[k]);
                point[i].y = point[i].x*tp.k + tp.b;
            }
        }
        double u,d,mid;
        u = 999999999999LL;
        d = 0.00;
        while(d <= u){
            mid = (u+d)/2;
            bool flag = 1;
            node s = point[0];
            s.v = mid*mid;
            for(int i = 1 ; i < n + m ; i ++){
                s.v = 2*(g*(s.y - point[i].y) + s.v/2);
                s.y = point[i].y;
                s.x = point[i].x;
                if(s.v < 0){
                    flag = 0;
                    break;
                }
                if(point[i].flag){
                    if(s.v <= point[i].v*point[i].v){
                        flag = 0;
                        break;
                    }
                }
            }
            if(flag){
                u = mid - eps;
            }
            else
                d = mid + eps;
        }
        printf("Case %d: %.2f\n",id++,fabs((u + d) / 2.0));
    }
    return 0;
}

http://www.cnblogs.com/nanke/archive/2011/09/12/2174032.html

#include<stdio.h>
#include<math.h>
#include<string.h>
struct  PEAK
{  
    double x,h;
}p[1100];
struct bit
{   
    double x,v;
}pat[1100];
int main()
{  
    int G=20; 
    double h,weight; 
    int t,cases=1,i,j,n,m,w;
    scanf("%d",&t); 
    while(t--) 
    {    
        double v0=0,temp;   
        scanf("%d%d%d",&n,&m,&w); 
        for(i=1;i<=n;i++) //求出到达任意一个峰顶需要的最小速度    
        { 
            scanf("%lf%lf",&p[i].x,&p[i].h);  
            if(p[i].h-p[1].h<=0)  //峰顶在起始点一下,初速度可以为零      
                temp=0;      
            else temp=sqrt(2*G*(p[i].h-p[1].h));    
            if(temp>v0) v0=temp;    
        }    
        double vx,v=0;    
        for(i=1;i<=m;i++)   //根据能量守恒,求出到达每一个bitter potato需要的最小速度
        {     
            scanf("%lf%lf%lf",&pat[i].x,&pat[i].v,&weight);  
            pat[i].x+=p[1].x;     //将bitter potato的坐标改为相对于原点
            for(j=1;j<n;j++)    
            {    
                if(pat[i].x>=p[j].x&&pat[i].x<=p[j+1].x)  //找出当前bitter potato所在的斜坡
                {           
                    h=(1.0*(p[j+1].h-p[j].h)/(p[j+1].x-p[j].x))*(pat[i].x-p[j].x) + p[j].h;  //bitter potatoe相对于原点的高度 
                    break;      
                }         
            }      
            vx=sqrt(1.0*pat[i].v*pat[i].v+1.0*2*G*(h-p[1].h)); //求出到达当前bitter potato需要的速度   
            if(vx>v)        
                v=vx;
        }    
        if(v>v0) 
            printf("Case %d: %.2lf\n",cases++,v);   
        else 
            printf("Case %d: %.2lf\n",cases++,v0); 
    }  
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值