zoukankan      html  css  js  c++  java
  • AGC023D

    题目链接:D - Go Home

    题目大意:一条街上有 (n) 个建筑,坐标分别为 (x_1,x_2,dots,x_n),第 (i) 个建筑是 (p_i) 个员工的家,有一辆车,开始是在 (S),里面乘坐着所有的员工,每一次员工会进行投票决定车想左还是右,员工们的投票策略是使得自己的回家时间最早。如果票一样多,向左行驶,如果一个员工投左、右时间一样长,投左,问所有员工到家的最晚时间。


    题解:如果 (x_1<S<x_n),则考虑 (1)(n) 号建筑,先给出结论:若 (p_1ge p_n) 则车会前往 (1) 否则会前往 (n)。接下来是证明:

    1. (n=2) 显然成立。
    2. (nge 3)(x_{n-1}<S) 显然除了第 (n) 座建筑的员工,都希望向左走。
    3. (nge 3)(x_{n-1}>S) 则若到达第 (1) 座建筑前为到达第 (n-1) 座建筑,则结论显然成立,否则转换为前两种情况。

    所以说车一定是先前往 (1) 号楼,然后在一路跑到 (n)

    那么 (n) 号楼员工回家的时间就是 (1) 号楼员工回家的时间加上 (x_n-x_1)

    所以说第 (n) 栋楼的员工一定会和第一栋楼的员工投一样的票。

    (p_1>p_n) 同理。

    所以直接递归,直到 (x_1<S<x_n) 的条件不满足为止,这可以直接算了。

    时间复杂度:(O(n))

    #include <cstdio>
    typedef long long ll;
    const int Maxn=100000;
    int n;
    int x[Maxn+5],s;
    ll p[Maxn+5];
    ll calc(int left,int right,int t){
    	if(s<x[left]){
    		return x[right]-s;
    	}
    	if(s>x[right]){
    		return s-x[left];
    	}
    	if(p[left]>=p[right]){
    		p[left]+=p[right];
    		return calc(left,right-1,left)+(t==right?x[right]-x[left]:0);
    	}
    	else{
    		p[right]+=p[left];
    		return calc(left+1,right,right)+(t==left?x[right]-x[left]:0);
    	}
    }
    int main(){
    	scanf("%d%d",&n,&s);
    	for(int i=1;i<=n;i++){
    		scanf("%d%lld",&x[i],&p[i]);
    	}
    	printf("%lld
    ",calc(1,n,p[1]<p[n]?1:n));
    	return 0;
    }
    
  • 相关阅读:
    CocosIDE导出Android APK的注意事项
    C++14尝鲜:Generic Lambdas(泛型lambda)
    silverlight调用WebService传递json接收绑定数据
    解决考试系统高并发数据载入不对问题
    汇编入门学习笔记 (九)—— call和ret
    Java SerialPort SDK
    how tomcat works 总结 二
    linux下多线程的调试
    垃圾回收GC:.Net自己主动内存管理 上(二)内存算法
    HDU-4973-A simple simulation problem.(线段树)
  • 原文地址:https://www.cnblogs.com/withhope/p/14242730.html
Copyright © 2011-2022 走看看