B1. Painting the Array I

目录

1.Problem

2.Input

3.Output

4.Examples

4.1input

4.2output

5.Code

6.Conclusion


1.Problem

The only difference between the two versions is that this version asks the maximal possible answer.

Homer likes arrays a lot. Today he is painting an array a1,a2,…,ana1,a2,…,an with two kinds of colors, white and black. A painting assignment for a1,a2,…,ana1,a2,…,an is described by an array b1,b2,…,bnb1,b2,…,bn that bibi indicates the color of aiai (00 for white and 11 for black).

According to a painting assignment b1,b2,…,bnb1,b2,…,bn, the array aa is split into two new arrays a(0)a(0) and a(1)a(1), where a(0)a(0) is the sub-sequence of all white elements in aa and a(1)a(1) is the sub-sequence of all black elements in aa. For example, if a=[1,2,3,4,5,6]a=[1,2,3,4,5,6] and b=[0,1,0,1,0,0]b=[0,1,0,1,0,0], then a(0)=[1,3,5,6]a(0)=[1,3,5,6] and a(1)=[2,4]a(1)=[2,4].

The number of segments in an array c1,c2,…,ckc1,c2,…,ck, denoted seg(c)seg(c), is the number of elements if we merge all adjacent elements with the same value in cc. For example, the number of segments in [1,1,2,2,3,3,3,2][1,1,2,2,3,3,3,2] is 44, because the array will become [1,2,3,2][1,2,3,2] after merging adjacent elements with the same value. Especially, the number of segments in an empty array is 00.

Homer wants to find a painting assignment bb, according to which the number of segments in both a(0)a(0) and a(1)a(1), i.e. seg(a(0))+seg(a(1))seg(a(0))+seg(a(1)), is as large as possible. Find this number.

2.Input

The first line contains an integer nn (1≤n≤1051≤n≤105).

The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤n1≤ai≤n).

3.Output

Output a single integer, indicating the maximal possible total number of segments.

4.Examples

4.1input

7
1 1 2 2 3 3 3

4.2output

6

5.Code

#include <bits/stdc++.h>

#define pb push_back
#define mp make_pair
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

template <typename T>
bool chkmax(T &x, T y) {
    return x < y ? x = y, true : false;
}

template <typename T>
bool chkmin(T &x, T y) {
    return x > y ? x = y, true : false;
}

int readint() {
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

int main() {
    int n = readint();
    vector<int> a(n + 1), nxt(n + 1, 0);
    vector<pii> v;

    for (int i = 1; i <= n; i++) {
        a[i] = readint();
    }

    int num = 1;
    for (int i = 2; i <= n; i++) {
        if (a[i] != a[i - 1]) {
            v.pb(mp(a[i - 1], num));
            num = 1;
        } else {
            num++;
        }
    }
    v.pb(mp(a[n], num));

    for (int i = v.size() - 1; i >= 0; i--) {
        nxt[i] = (v[i].se >= 2) ? v[i].fi : nxt[i + 1];
    }

    int now0 = 0, now1 = 0, ans = 0;
    for (int i = 0; i < v.size(); i++) {
        if (v[i].se >= 2) {
            ans += (now0 != v[i].fi) + (now1 != v[i].fi);
            now0 = now1 = v[i].fi;
        } else {
            ans += (v[i].fi == nxt[i]) ? (now0 != v[i].fi) + (now1 != v[i].fi) :
                   (now0 == nxt[i]) ? (now0 = v[i].fi, 1) :
                   (now1 == nxt[i]) ? (now1 = v[i].fi, 1) :
                   (now0 != v[i].fi) + (now1 != v[i].fi);
        }
    }

    printf("%d\n", ans);
    return 0;
}

6.Conclusion

        上述代码的作用是统计一个整数序列中,相邻且相同的数字的连续长度,并计算满足条件的不同数字的个数。这个统计过程包括以下步骤:

        1.通过readint函数读入整数n,表示序列的长度。
        2.通过循环读入n个整数到数组a中。
        3.遍历数组a,将相邻且相同的数字进行压缩,记录每个压缩后的数字和其连续的长度。压缩后的结果存储在vector&gt; v 中。
        4.从压缩后的结果中构建数组nxt,其中nxt[i]表示v[i].se(连续长度)大于等于2时的v[i].fi(数字值),否则为nxt[i+1]的值。
        5.使用变量now0和now1记录当前已经遍历过的不同数字,以及变量ans记录满足条件的不同数字的个数。
        6.遍历压缩后的结果v,根据不同情况更新now0、now1和ans的值。
        7.最后输出ans,即统计的结果。

总体来说,这段代码的目的是对一个整数序列进行压缩并统计满足条件的不同数字的个数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向阳而生__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值