0%

4007.非零段划分

4007. 非零段划分

题目描述:

A1,A2,,AnA1,A2,,An 是一个由 nn 个自然数(非负整数)组成的数组。

我们称其中 Ai,,AjAi,,Aj 是一个非零段,当且仅当以下条件同时满足:

  • 1ijn1ijn
  • 对于任意的整数 kk ,若 ikjikj ,则 Ak>0Ak>0
  • i=1i=1Ai1=0Ai1=0
  • j=nj=nAj+1=0Aj+1=0

下面展示了几个简单的例子:

  • A=[3,1,2,0,0,2,0,4,5,0,2]A=[3,1,2,0,0,2,0,4,5,0,2] 中的 44 个非零段依次为 [3,1,2][2][4,5][3,1,2][2][4,5][2][2]
  • A=[2,3,1,4,5]A=[2,3,1,4,5] 仅有 11 个非零段;
  • A=[0,0,0]A=[0,0,0] 则不含非零段(即非零段个数为 00 )。

现在我们可以对数组 AA 进行如下操作:任选一个正整数 pp ,然后将 AA 中所有小于 pp 的数都变为 00

试选取一个合适的 pp ,使得数组 AA 中的非零段个数达到最大。

若输入的 AA 所含非零段数已达最大值,可取 p=1p=1 ,即不对 AA 做任何修改。

输入格式

输入的第一行包含一个正整数 nn

输入的第二行包含 nn 个用空格分隔的自然数 A1,A2,,AnA1,A2,,An

输出格式

仅输出一个整数,表示对数组 AA 进行操作后,其非零段个数能达到的最大值。

数据范围

70%70% 的测试数据满足 n1000n1000
全部的测试数据满足 n5×105n5×105 ,且数组 AA 中的每一个数均不超过 104104

输入样例1:

1
2
11
3 1 2 0 0 2 0 4 5 0 2

输出样例1:

1
5

输入样例2:

1
2
14
5 1 20 10 10 10 10 15 10 20 1 5 10 15

输出样例2:

1
4

输入样例3:

1
2
3
1 0 0

输出样例3:

1
1

输入样例4:

1
2
3
0 0 0

输出样例4:

1
0

题解:

与 2014.岛 类似 2014.岛 | Luobuyu’s Blog

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
using namespace std;
using namespace FAST_IO;
const ll mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const ll INF_LL = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-5;
const int maxn = 5e5 + 10;
const int maxm = 1e5 + 10;
int t, n, m, k;
int a[maxn];
pair<int, int> q[maxn];
int main()
{
// #define COMP_DATA
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for (int i = 1; i <= n; i++)
{
// read(a[i]);
cin >> a[i];
}
// 去重
n = unique(a + 1, a + 1 + n) - a - 1;

// 离散化是需要把id进行映射,将 a[i] 比较大的数映射为比较小的
// 可以使用 map 进行处理,分配 map.size() + 1
for (int i = 1; i <= n; i++)
{
q[i] = {a[i], i};
}
sort(q + 1, q + 1 + n);
bool flag = 0;
int minx = INF;
int maxx = -1;
for (int i = 1; i <= n; i++)
{
minx = min(minx, a[i]);
maxx = max(maxx, a[i]);
}
if (minx == maxx)
{
cout << 0 << endl;
return 0;
}
int cnt = 1;
int ans = 1;
a[0] = a[n + 1] = 0;
for (int i = 1; i <= n; i++)
{
int id = q[i].second;
if (a[id] > a[id - 1] && a[id] > a[id + 1])
cnt--;
else if (a[id] < a[id - 1] && a[id] < a[id + 1])
cnt++;
// 其他两种是同构的,而且是cnt保持不变
if (q[i].first != q[i + 1].first)
ans = max(ans, cnt);
}
cout << ans << endl;
return 0;
}
Powered By Valine
v1.5.1