题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=6669
思路:
考虑每相邻区间之间是否有交集,如果有交集,就不用计算贡献更新交集后跳过;否则,计算最少的步数,每次走左边或者走右边最近的一个就好了,区间更新为移动后的区间交集。如果间距为奇数,新的交集区间长度为2,否则为1。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int l[N],r[N],n,T;
int main(void)
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int ans = 0;
scanf("%d%d",&l[1],&r[1]);
int l1 = l[1],r1 = r[1];
for(int i=2;i<=n;i++){
scanf("%d%d",&l[i],&r[i]);
int tl = max(l[i],l1),tr = min(r[i],r1);
if(tl <= tr){ //有相同区间
l1 = tl; r1= tr;
}
else{
if(r1 < l[i]){
ans += (l[i] - r1 + 1)/2;
if(r[i] == l[i]){
l1 = r1 = l[i];
}
else{
if((l[i] - r1)%2) l1 = l[i],r1 = l[i]+1;
else l1 = l[i],r1 = l[i];
}
}
else{
ans += (l1 - r[i] + 1)/2;
if(r[i] == l[i]){
l1 = r1 = l[i];
}
else{
if((l1-r[i])%2) l1 = r[i]-1,r1 = r[i];
else l1 = r[i],r1 = r[i];
}
}
}
}
printf("%d\n",ans);
}
return 0;
}