zoukankan      html  css  js  c++  java
  • 模拟祭-电灯-题解

    传送门

    我一个蒟蒻是真的太弱了

    (我也很难受...可是...)

    先%%%维护oj的大佬lsy

    再%%%秒题的大佬lyn

     

    我真的卑微至极了

    ------------------------------------------------------------

    题目描述

    有 n 个灯泡排成一列。每个灯泡可能是点亮或熄灭的。有一台操控灯泡的机器,每一次可以选择一段连续区间,让这段连续区间中熄灭的灯泡全部点亮,亮着的灯泡全部熄灭。但由于机器已经老化,仅能再使用一次了。

    你可以认为点亮的灯泡与熄灭的灯泡交替排列的样子(下面称这样的灯泡列为交替列)很好看。现在,你希望珍惜最后一次操控灯泡的机会,使得操控后这列灯泡中最长的交替列尽可能地长。

    例如,这列灯泡若原本如下所示(○ 表示点亮的灯泡,● 为熄灭的灯泡):

    ○ ○ ● ● ○ ● ○ ○ ○ ●

    如果选择第 4 个到第 7 个灯泡,则会变成如下的形式:

    ○ ○ ● ○ ● ○ ● ○ ○ ●

    此时,最长的交替列为第 2 个到第 8 个灯泡,长度为 7。

    而如果仅选择第 8个灯泡,则会变成如下的形式: ○ ○ ● ● ○ ● ○ ● ○ ●

    此时,最长的交替列为第 4 个到第 10 个灯泡,长度也为 7。

    可以发现,此例中没有方法能使得最长交替列长度大于 7,则 7 即为答案。

    输入格式

    输入文件第一行一个正整数 n,表示灯泡的数量。 第二行包含 n 个数字,每个数字均为 0 或 1,依次代表序列中每个灯泡的初始状态。1 代表点亮,0 代表熄灭。

    输出格式

    输出一个整数,表示所有能得到的灯泡列中最长的交替列的长度。

    样例

    Input 1:

    10
    1 1 0 0 1 0 1 1 1 0

    Output 1:

    7

    Input 2:

    5 
    1 1 0 1 1

    Output 2:

    5
    提示与说明

    对于 30%的数据,1≤n≤500。

    对于 60%的数据,1≤n≤2000。

    对于 100%的数据,1≤n≤100000。

     

    ---------------------------------------------------------------

    思路:

    遇到相邻的灯泡状态相同的,就分块

    那么

    就可以把整体分成多个块(特殊情况:就一个块)

    每个块中:是交替列

    既然分块

    那么每个块两边必然是和它不同的

    那么

    把它反转就可以和他两边的块组成大块

    所以

    我们只需要找到相邻3个块加起来的长度最大的值就可以了

     

     再用上前缀和维护就可以啦!!!

    #include<cstdio>
    using namespace std;
    
    int n;
    int a[100005];
    int cnt;
    int list[100005];
    
    int main()
    {
        scanf("%d",&n);
        for(int i = 1;i <= n;i++)
            scanf("%d",&a[i]);
        int flg = 0;
        for(int i = 1;i <= n;i++)
        {
            if(flg>0)
                if(a[i] == a[i-1])
                {
                    list[++cnt] = flg;
                    flg = 0;
                }
            flg++;
        }
        if(flg > 0)
            list[++cnt] = flg;
        int tot=0;
        int max = 0;
        for(int i = 1;i <= cnt;i++)
        {
            tot += list[i];
            if(i >= 4)
                tot -= list[i - 3];
            if(max < tot)
                max = tot;
        }
        printf("%d
    ",max);
        return 0;
    } 
  • 相关阅读:
    反射 动态导入 元类
    面向对象的继承
    面向对象基础总结
    面向对象基础
    包 logging hashlib copy模块
    os random sys json 模块
    【1012 | Day 43】前端之CSS(下)
    【1011 | Day 42】灵魂拷问:数据放在服务端和客户端的利与弊?
    【1011 | Day 42】socket实现ftp文件的上传和下载
    【1011 | Day 42】前端之CSS(上)
  • 原文地址:https://www.cnblogs.com/darlingroot/p/10437929.html
Copyright © 2011-2022 走看看