2 solutions

  • 3
    @ 2022-10-18 18:03:21

    额外拨动开关,则该时间点之后所有原来的亮灯时间变为熄灯时间,熄灯时间变为亮灯时间,即交换了亮熄灯时间。

    所以若是某次拨动开关的时间点之后的总熄灯时间大于总亮灯时间,我们可以在该时间点之后额外添加一个拨动开关的时间点,后边的总亮灯时间和总灭灯时间就会交换,这样总体亮灯时间就会变长

    所以我们只需要从数组的末尾开始遍历,找哪个拨动开关的时间点a[i]后边的总熄灯时间-总亮灯时间为正值且差值最大,就在这个时间点a[i]后边相邻的时间点额外拨动一次开关交换后边的熄灯和亮灯时间,这样最长亮灯时间就=该a[i]点前边的总亮灯时间+该a[i]点之后的总灭灯时间-1(相邻两个时间点之间的灯的状态并未改变)

    当然,若是每次拨动开关的点位之后的总熄灯时间-总亮灯时间为负值,则不用额外添加拨动开关。

    核心代码:

     //输入并计算存取每个点前边总开灯时间
            for(i=1;i<=n;i++)
            {
                scanf("%d",&x[i]);
                if(i%2==1)k+=x[i]-x[i-1];
                y[i]=k;
            } 
            //计算并存取每个点后边总关灯时间
            x[n+1]=m;
            int g=0;//总关灯时间
            k=0;
            int cha;//每个点后边关灯时间-开灯时间的差值
            int max=0;//最大差值
            int maxn;//最大差值点  
            for(i=n;i>=0;i--)
            {
                if(i%2==0)
                    k+=x[i+1]-x[i];
                else
                    g+=x[i+1]-x[i];
                z[i]=g;  
                cha=g-k;  
                if(cha>max)
                {
                    max=cha;
                    maxn=i;
                }      
            }
    

    Information

    ID
    816
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    8
    Tags
    # Submissions
    43
    Accepted
    7
    Uploaded By