zoukankan      html  css  js  c++  java
  • 一本通1600【例 4】旅行问题

    1600:【例 4】旅行问题

    时间限制: 1000 ms         内存限制: 524288 KB

    【题目描述】

    原题来自:POI 2004

    John 打算驾驶一辆汽车周游一个环形公路。公路上总共有 n 车站,每站都有若干升汽油(有的站可能油量为零),每升油可以让汽车行驶一千米。John 必须从某个车站出发,一直按顺时针(或逆时针)方向走遍所有的车站,并回到起点。在一开始的时候,汽车内油量为零,John 每到一个车站就把该站所有的油都带上(起点站亦是如此),行驶过程中不能出现没有油的情况。

    任务:判断以每个车站为起点能否按条件成功周游一周。

    【输入】

    第一行是一个整数 n,表示环形公路上的车站数;

    接下来 n 行,每行两个整数 pi,di ,分别表示表示第 i 号车站的存油量和第 i 号车站到下一站的距离。

    【输出】

    输出共 n 行,如果从第 i 号车站出发,一直按顺时针(或逆时针)方向行驶,能够成功周游一圈,则在第 i行输出 TAK,否则输出 NIE

    【输入样例】

    5
    3 1
    1 2
    5 2
    0 1
    5 4

    【输出样例】

    TAK
    NIE
    TAK
    NIE
    TAK

    【提示】

    数据范围与提示:

    对于全部数据,3n106,0pi2×109,0<di2×109

    sol:若一个点是不能环绕一圈的,那么就是这个点在绕一圈过程中油量的最小值<0,每个点对当前油的贡献就是pi-di,这样就可以维护出一个前缀和,(断环成链后长度为2n),i点是否合法就是判断(S[i]~S[i+n-1]中的最小值-S[i])是否小于0,小于0就不可以,逆时针一模一样搞一遍,就是pi和di会变一下,随便处理一下就可以了

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
        ll s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-');
            ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48);
            ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-');
            x=-x;
        }
        if(x<10)
        {
            putchar(x+'0');
            return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    inline void writeln(ll x)
    {
        write(x);
        putchar('
    ');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) writeln(x)
    const int N=1000005;
    int n,You[N<<1],Dis[N<<1],You1[N<<2],Dis1[N<<1],Oil[N<<1];
    ll Sum[N<<1];
    bool ans[N<<1];
    struct Data
    {
        ll Shuz;
        int Weiz;
    }Ddq[N<<1];
    int main()
    {
        int i,Head,Tail;
        R(n);
        for(i=1;i<=n;i++)
        {
            You[i]=You[i+n]=read();
            Dis[i]=Dis[i+n]=read();
            Oil[i]=Oil[i+n]=You[i]-Dis[i];
        }
        Head=1; Tail=0;
        for(i=1;i<=n+n;i++)
        {
            Sum[i]=Sum[i-1]+Oil[i];
            while(Head<Tail&&Ddq[Head].Weiz<i-n+1) Head++;
            if(i>=n)
            {
                if(Ddq[Head].Shuz-Sum[i-n]<0) ans[i-n+1]=0;
                else ans[i-n+1]=1;
            }
            while(Head<=Tail&&Ddq[Tail].Shuz>Sum[i]) Tail--;
            Ddq[++Tail]=(Data){Sum[i],i};
        }
        for(i=1;i<=n;i++)
        {
            You1[i]=You[n-i+2];
            Dis1[i]=Dis[n-i+1];
            Oil[i]=Oil[i+n]=You1[i]-Dis1[i];
        }
        Head=1; Tail=0;
        for(i=1;i<=n+n;i++)
        {
            Sum[i]=Sum[i-1]+Oil[i];
            while(Head<Tail&&Ddq[Head].Weiz<i-n+1) Head++;
            if(i>=n)
            {
                if(Ddq[Head].Shuz-Sum[i-n]>=0)
                {
                    (i==n)?(ans[1]=1):(ans[n-(i-n+1)+2]=1);
                }
            }
            while(Head<=Tail&&Ddq[Tail].Shuz>Sum[i]) Tail--;
            Ddq[++Tail]=(Data){Sum[i],i};
        }
        for(i=1;i<=n;i++)
        {
            (ans[i])?puts("TAK"):puts("NIE");
        }
        return 0;
    }
    /*
    input
    5
    3 1
    1 2
    5 2
    0 1
    5 4
    output
    TAK
    NIE
    TAK
    NIE
    TAK
    
    input
    10
    4 3
    10 5
    5 0
    18 0
    2 7
    5 7
    3 2
    2 9
    10 3
    6 9
    output
    TAK
    TAK
    TAK
    TAK
    TAK
    NIE
    NIE
    NIE
    TAK
    NIE
    */
    View Code
  • 相关阅读:
    net事件丢失解决方法
    Google排名经验谈
    动力漏洞
    Understand简明参考
    修复iReaper
    Bootstrap源码分析
    UTF8编码字节流错误小析
    OAuth2学习及DotNetOpenAuth部分源码研究
    DynamicModuleUtility对象在.net不同版本下的兼容性问题
    MediaWiKi简明安装与配置笔记
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/10371934.html
Copyright © 2011-2022 走看看