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;
}