牛客-小d和孤独的区间
题目如上
1
s
1s
1s的时间限制,说明我们应该找到一种“巧法”
根据提示,我们只需要找到“中间全部都是
0
0
0,只有一个1的区间”即可
但是在找的途中,我们不仅要顾及当前
1
1
1之前的
0
0
0的个数,我们还要注意顾及
1
1
1之后的
代码:
#include<iostream>
using namespace std;
int n;
int main() {
cin >> n;
long long res = 0;//必须要开long long
//index存最新的1的下标,cnt存0的个数加上当前1本身
long long index = 0; long long cnt = 0;
for (int i = 1; i <= n; i++) { //变读入边运算
int a;cin >> a;
if (a) { //如果读到了1
cnt = i - index; //更新一下这个1和前面的1之间的0的个数
index = i; //记录下这个1的位置
}
res += cnt; //每次循环都让答案加上cnt
}
cout << res;
return 0;
}
或许你会一头雾水,为什么每次都要加上 c n t cnt cnt ?而不是当 a a a等于 1 1 1的时候或者是 a a a等于 0 0 0的时候之类的。
我们以一组输入为例:为了顾及理解的方便,此数是比较特殊的情况。
5
0 0 1 0 0
我们拿出笔对其进行模拟。
首先,我们输入了前两个 0 0 0,这时候变量都没有任何改变。
当我们输入第三个
1
1
1的时候,
c
n
t
cnt
cnt变为了
3
3
3,之后
i
n
d
e
x
index
index变为了
3
3
3。这时候答案加上了
3
3
3。
**这时候的三包含了什么含义?**首先,在一个只有一个1的区间之中,每个0都与1产生了一个区间,在此例子中便是:0 0 1
(
[
1
,
3
]
),
([ 1 , 3 ]),
([1,3]),0 1
(
[
2
,
3
]
),
([ 2 , 3 ]),
([2,3]),在之后,每个1都可以自己组成一个区间,那么就正好是
3
3
3个区间。
之后我们又输入了两个 0 0 0,然后我们的答案加了两次 3 3 3,为什么?
我们从第四个
0
0
0开始看,当我们增加这一个
0
0
0之后,前面的
0
0
0与这个
0
0
0可以联动起来,能够再次组成三个区间,即:
0 0 1 0
(
[
1
,
4
]
),
([ 1 , 4 ]),
([1,4]),0 1 0
(
[
2
,
4
]
),
([ 2 , 4 ]),
([2,4]),1 0
(
[
3
,
4
]
),
([ 3 , 4 ]),
([3,4]),故我们可以得到一个结论,在这之后,每增加
1
1
1个
0
0
0,都会增加
i
n
d
e
x
index
index指向的1的前面
0
0
0与
1
1
1能够组成的区间数。
由此我们就可以得到代码。