题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6669
在线处理!!
先找到从哪个位置落脚,一定是先从第一个区间找,如果第一个区间与第二个区间有交集,那么就用交集和第三个区间比较,直到没有交集或者处理完n个区间
找到没有交集的时候 只有两种情况
第一种
第二种
然后计算出第一次落在哪个位置,然后确定方向,如果当前位置到下一区间的方向和你标记的方向相同,并且上一个区间不是一个点,且距离是奇数,那么你就可以往当前方向移动一个位置(这是坑点)
下面附几个卡人的样例
#include <cstdio>
#include <iostream>
#define ll long long
using namespace std;
const int maxn = 1005;
int a[maxn], b[maxn];
int s, n, dir, tmp;
ll ans;
int solve(int n){
int st = a[1], ed = b[1];
for(int i = 2; i <= n; i++) {
if(st <= a[i] && a[i] <= ed)
if(a[i] <= st && ed <= b[i]) continue;
if(a[i] >= st && a[i] <= ed && b[i] >= ed) {
st = a[i];
}
else if(a[i] >= st&& b[i] <= ed) {
st = a[i];
ed = b[i];
}
else if(a[i] <= st && b[i] <= ed && b[i] >= st) {
ed = b[i];
}
else if(ed < a[i]) {
tmp = a[i] - ed;
ans += (a[i] - ed + 1) / 2;
s = a[i];
dir = 1;
return i+1;
}
else if(st > b[i]) {
tmp = st - b[i];
ans += (st - b[i] + 1) / 2;
s = b[i];
dir = -1;
return i+1;
}
}
return n + 1;
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
ans = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d%d", &a[i], &b[i]);
}
int i = solve(n);
for(; i <= n; i++) {
if(a[i] >= s) {
if(dir == 1) {
if((tmp & 1) && b[i - 1] > a[i - 1])
s++;
}else {
dir = 1;
}
ans += (a[i] - s + 1) / 2;
tmp = a[i] - s;
s = a[i];
}
else if(b[i] <= s) {
if(dir == -1) {
if((tmp & 1) && b[i - 1] > a[i - 1])
s--;
}else {
dir = -1;
}
tmp = s - b[i];
ans += (s - b[i] + 1) / 2;
s = b[i];
dir = -1;
}
}
printf("%I64d\n", ans);
}
return 0;
}
/*
4
5
1 7
4 10
2 3
5 6
8 9
6
1 7
4 10
2 3
5 6
8 9
11 12
7
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
4
1 2
5 7
3 6
10 11
*/