Game 2019 年百度之星·程序设计大赛 - 初赛一 思维

Game

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 547    Accepted Submission(s): 107


 

Problem 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。

 

#include <stdio.h>
#include <algorithm>
#define N 1020
using namespace std;
int a[N], b[N];
int main() {
    int t, n, l, r, i;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        scanf("%d%d", &a ,&b);
        
        for(i=1; i<n; i++)
            scanf("%d%d", &a[i], &b[i]);
        l=a[0];r=b[0];
        for(i=1; i<n; i++) {                        //选相交区间
            if(max(l, a[i])>min(r, b[i]))
                break;
            l=max(l, a[i]);
            r=min(r, b[i]);
        }
        if(i==n)                                 //所有任务完成,结束
        {
            printf("0\n");
            continue;
        }
        int ans=0, sum;
        
        if(b[i]<l) 
            sum=l;  
        else sum=r;
        int temp=0;
  
        for(; i<n-1; i++)                     //没有考虑最后一个,因为要用到 i+1 项任务
        {
            if(sum>b[i]) {
                if (temp==-1)                 //步数可以移动
                    sum--;
                ans+=(sum-b[i]+1)/2;           //更新步数
                if((sum-b[i])%2==1 && b[i]-a[i]>=1)      //判断区间只有一个点的情况
                    temp=-1;                       //更新可以移动的步数
                else temp=0;      
                sum=b[i];                        //更新位置
            }
            else if(sum < a[i]) {
                if (temp==1)
                    sum++;
                ans+=(a[i]-sum+1)/2;
 
                if((a[i]-sum)%2==1 && b[i]-a[i]>=1)
                    temp=1;
                else temp=0;
                sum=a[i];
            }
            else {
                if (sum==a[i] && temp==-1)
                    temp=0;
                else if (sum==b[i] && temp==1)
                    temp=0;
            }
        }
        //printf("!%d %d %d\n", sum, ans, temp);
        if(sum>b[i]) {                    //考虑最后一个
            if (temp==-1)
                sum--;
            ans += (sum-b[i] + 1)/2;
        }
        else if(sum<a[i]) {
            if (temp==1)
                sum++;
            ans+=(a[i]-sum+1)/2;
        }
        
        printf("%d\n",ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值