hdu 6669(贪心+思维)

题目连接: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;
}
发布了438 篇原创文章 · 获赞 16 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_41829060/article/details/104056699