zoukankan      html  css  js  c++  java
  • BZOJ2328: [HNOI2011]赛车游戏

    BZOJ2328: [HNOI2011]赛车游戏

    Description


    题解Here!

    一开始被题面那一长串的描述吓到了,一直没敢做。。。
    然后尝试着硬着头皮读懂题面。
    然后。。。这不是贪心么???

    从耗油量最少开始慢慢贪心地调整。
    对于上坡,速度设为$0$,但是免不了耗油,这一部分的耗油先减掉。
    对于下坡,速度在不耗油的前提下设到最大(但是不能超过$vmax$)。
    对于平路,速度设为$0$。
    然后我们用一个优先队列来维护这些线段,每次取出速度最小的段,如果它的速度和次小的速度一样就合并起来,否则将它的速度提升到和次小的速度一样。

    当然这是在油够用的前提下,如果油不够用就提到能提到的最高速率。
    这样做直到用光油或者都打到$vmax$时结束。
    证明?$ an(frac{pi}{2}+kpi),kin Z$。。。

    附代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #define eps (1e-8)
    using namespace std;
    int n;
    double A,B,maxn,f;
    bool flag;
    struct node{
    	double oil,dis;
    	friend bool operator <(const node &p,const node &q){
    		return p.oil>q.oil;
    	}
    };
    priority_queue<node> q;
    inline int check(double x){
    	if(fabs(x)<eps)return 0;
    	return (x>0?1:-1);
    }
    void work(){
    	if(!flag){
    		printf("IMPOSSIBLE
    ");
    		while(!q.empty())q.pop();
    		return;
    	}
    	double w,ans=0;
    	node u,v;
    	q.push((node){maxn,0});
    	while(check(f)>0&&!q.empty()){
    		u=q.top();
    		q.pop();
    		v=q.top();
    		if(check(u.oil-maxn)==0)ans+=u.dis/u.oil;
    		else if(check(u.oil-v.oil)!=0){
    			w=f/(A*u.dis);
    			if(check(u.oil-v.oil+w)>=0){
    				w=v.oil-u.oil;
    				q.pop();
    				q.push((node){v.oil,u.dis+v.dis});
    			}
    			else{
    				u.oil+=w;
    				q.push(u);
    			}
    			f-=A*w*u.dis;
    		}
    		else{
    			q.pop();
    			q.push((node){v.oil,u.dis+v.dis});
    		}
    	}
    	while(!q.empty()){
    		u=q.top();
    		q.pop();
    		ans+=u.dis/u.oil;
    	}
    	printf("%.5lf
    ",ans);
    }
    void init(){
    	double x,y,w,l;
    	scanf("%lf%lf%lf%lf%d",&A,&B,&maxn,&f,&n);
    	flag=true;
    	for(int i=1;i<=n;i++){
    		scanf("%lf%lf",&x,&y);
    		x/=1000.0;y/=1000.0;
    		w=y/x;
    		l=sqrt(x*x+y*y);
    		if(check(w)>0){
    			f-=w*B*l;
    			q.push((node){0,l});
    			if(check(f)<=0)flag=false;
    		}
    		else if(check(w)<0)q.push((node){min(-w*B/A,maxn),l});
    		else q.push((node){0,l});
    	}
    }
    int main(){
    	int t;
    	scanf("%d",&t);
    	while(t--){
    		init();
    		work();
    	}
        return 0;
    }
    
  • 相关阅读:
    面试题47题
    深度学习面试
    神经网络训练中的梯度消失与梯度爆炸
    Softmax函数与交叉熵
    sourceTree 添加 ssh key 方法
    request.form()和request()的区别
    C#中Request.ServerVariables详细说明及代理
    Page_Load事件与IsPostBack属性
    CSS中position的absolute和relative用法
    读取游标
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9795187.html
Copyright © 2011-2022 走看看