欢迎来到Vijurria的博客|

Vijurria

园龄:2年11个月粉丝:6关注:2

Codeforces Round #823 (Div. 2) B. Meeting on the Line(贪心/思维/二分)

https://codeforces.com/contest/1730/problem/B

题目大意:

给定n个人,他们都住在坐标线上,第i个人住在xi点(1≤i≤n)。

他们想选择一个位置x0来满足。

第i个人将花费|Xi-x0|分钟到达会面地点,同样,第i个人需要ti分钟穿衣服,所以他或她总共需要ti+|Xi-x0|分钟。

这些人要求你找出一个位置x0,使所有n个人能在集合地点集合的时间最小化。

误差可以在1e(-6)的范围内。
inputCopy
7
1
0
3
2
3 1
0 0
2
1 4
0 0
3
1 2 3
0 0 0
3
1 2 3
4 1 2
3
3 3 3
5 3 3
6
5 4 7 2 10 4
3 2 5 1 4 6
outputCopy
0
2
2.5
2
1
3
6

一开始认为只能二分写,看到了这个写法,直呼太奇妙了

思维解读

  • 假如有n个人,每个人所在的地点可以是不同的,但是t假设都为0,所以我们可以知道,最完美的聚集点一定是取最左边和最右边的平均数;

  • 同时,题目我们就可以拆解为:一个在xi,需要ti的人,可以拆解为位置在xi-ti,0和xi+ti,0 这样两个人,这n个人都可以这样拆解成2*n个人;

【比如最终确定的汇合点x0在(xi,ti)的右侧,那么拆完后,(xi,ti)和(xi-ti,0)是等价的(到达聚集点的时间一样),而(xi+ti,0)到x0的时间一定小于(xi-ti,0),所以最大值没变】

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1000020;
const LL N=200200,M=2002;
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    int T=1;
    cin>>T;
    while(T--)
    {
        LL n;
        cin>>n;
        vector<LL> x(n+2),t(n+2),v;
        for(LL i=0;i<n;i++)
            cin>>x[i];
        for(LL i=0;i<n;i++)
        {
            cin>>t[i];
            v.push_back(x[i]-t[i]);
            v.push_back(x[i]+t[i]);
        }
        sort(v.begin(),v.end());
        LL minn=v[0];
        LL maxn=v[v.size()-1];
        cout<<(maxn+minn)/2;
        if((maxn+minn)%2==1) cout<<".5";
        cout<<endl;
    }
    return 0;
}

二分写法再补

本文作者:Vijurria

本文链接:https://www.cnblogs.com/Vivian-0918/p/16741733.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Vijurria  阅读(60)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起