HDU 6669 Game

hdu題面spa

解題思路

首先咱們要選一個起點,這個起點應該在第一個區間內,而後再看第二個區間在左邊仍是右邊以便移動,但轉念一想,咱們能夠把起點直接選在前一堆區間的交集上,因而思路就有了——依次把全部區間取交集,若是沒有交集就搞一個新的區間,以後的接着取交集,獲得一堆合併出來的區間。而後就在合併的區間上移動就好。.net

有一個細節要注意。舉個例子,若是如今位置在\(3\),以後的兩個目標區間依次是\([6,7]\)\([9,10]\),那麼咱們若是通過兩次移動(先1後2)到達第一個區間的左端點\(6\),下一步就要再移動兩次才能到達\(9\),因此第一步不妨用相同的代價(兩次移動)多走點,走到7,那麼第二步到\(9\)就只用移動一次就好。code

比賽時合併區間寫的有問題,WA*7,最後兩題慘淡收場……ip

源代碼

#include<cstdio>
#include<algorithm>
int T,n;
struct D{
    int a,b;
}p[1010];
int num;
int l,r;
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        num=0;
        scanf("%d%d%d",&n,&l,&r);
        for(int i=1,a,b;i<n;i++)
        {
            scanf("%d%d",&a,&b);
            if(a>r||b<l)
            {
                p[num++]={l,r};
                l=a;
                r=b;
            }
            else
            {
                l=std::max(l,a);
                r=std::min(b,r);
            }
            if(i==n-1) p[num++]={l,r};//比賽時這句話被我寫到循環外面去了……
        }
        int pos;
        if(p[0].b<p[1].a) pos=p[0].b;
        else pos=p[0].a;
        long long ans=0;
        for(int i=1;i<num;i++)
        {
            if(pos<p[i].a)//向右走
            {
                int delta=p[i].a-pos;
                pos=p[i].a;
                ans+=delta>>1;
                if(delta&1)
                {
                    ans++;
                    if(i+1<num&&pos+1<=p[i].b&&p[i+1].a>pos) pos++;
                }
            }
            else//向左走
            {
                int delta=pos-p[i].b;
                pos=p[i].b;
                ans+=delta>>1;
                if(delta&1)
                {
                    ans++;
                    if(i+1<num&&pos-1>=p[i].a&&p[i+1].b<pos) pos--;
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}
相關文章
相關標籤/搜索