【2019百度之星初赛一B题 HDU 6669 --- Game】

【2019百度之星初赛一B题 HDU 6669 --- Game】


Description

度度熊在玩一个好玩的游戏。
游戏的主人公站在一根数轴上,他可以在数轴上任意移动,对于每次移动,他可以选择往左或往右走一格或两格。
现在他要依次完成 n 个任务,对于任务 i,只要他处于区间 [ai,bi] 上,就算完成了任务。
度度熊想知道,为了完成所有的任务,最少需要移动多少次?
度度熊可以任意选择初始位置。

Input

第一行一个整数 T (1≤T≤10) 表示数据组数。
对于每组数据,第一行一个整数 n (1≤n≤1000) 表示任务数。
接下来 n 行,第 i 行两个整数 ai,bi (1≤ai≤bi≤1000000) 表示任务对应的区间。

Output

对于每组数据,一行一个整数表示答案。

Sample Input

1
2
1 10
20 30

Sample Output

5

样例描述
选取10为起点,经过的轨迹为10-12-14-16-18-20。

解题思路

根据题意可知,需要依次完成任务,那么我们只需要进行简单的模拟就行了。
在模拟过程中,首先初始化可以初始位置所在的区间即[1,1000000];
每次完成任务,只需找到在区间内某一点或者某一区间到该任务最近距离,然后更新位置区间。
在准备完成下一个任务时:

  1. 两个区间重合,只需更新位置区间的区间大小为当前重合部分。
  2. 当两个区间不重合时,计算位置区间到达下一个任务区间的最小值。并更新区间。

注意:当区间不重合时并且两个区间之间最短距离为奇数时,并且任务区间的左右端点不相等时,在相同步数下可以是任务区间的端点,也可能是任务区间内的端点的相邻点(对于当前任务步数是一样的,但是对于后面的任务,可能会使步数更优。)。所以更新位置区间时,左右端点不一定相等。

AC代码:

#include 
#include 
#include 
using namespace std;
int l,r;

int fun(int x,int y)
{
    int ll=max(l,x),rr=min(r,y);
    if(ll <= rr)
    {
        l=ll;
        r=rr;
        return 0;
    }
    if (y < l)
    {
        int res = (l - y + 1) / 2;
        r = y;
        if ((l - y & 1) && x < y)
            l = y - 1;
        else 
            l = y;
        return res;
    }
    else if(x > r)
    {
        int res = (x - r + 1) / 2;
        l = x;
        if ((x - r & 1) && x < y)
            r = x + 1;
        else 
            r = x;
        return res;
    }
    return 0;
}

int main()
{
    std::ios::sync_with_stdio(false);
    int T;
    cin >> T;
    while(T--)
    {
        int n,x,y,ans=0;
        l=1;
        r=1000000;
        cin >> n;
        for(int i=1;i<=n;i++)
        {
            cin >> x >> y;
            ans += fun(x,y);
        }
        cout << ans << endl;
    }
    return 0;
}

你可能感兴趣的:(百度之星,ACM)