0
点赞
收藏
分享

微信扫一扫

非零段划分

王小沫 2023-12-10 阅读 24

试题编号: 202109-2 试题名称: 非零段划分 时间限制: 1.0s 内存限制: 512.0MB 问题描述:

题目描述 A1,A2,…,An是一个由 n 个自然数(非负整数)组成的数组。我们称其中 Ai,…,Aj 是一个非零段,当且仅当以下条件同时满足: ·1≤i≤j≤n; ·对于任意的整数 k,若 i≤k≤j,则 Ak>0; ·i=1 或 Ai-1=0; ·j=n 或 Aj+1=0。 下面展示了几个简单的例子: ·A = [3, 1, 2, 0, 0, 2, 0, 4, 5, 0, 2] 中的 4 个非零段依次为 [3, 1, 2]、[2]、[4, 5] 和 [2]; ·A = [2, 3, 1, 4, 5] 仅有 1 个非零段; ·A = [0, 0, 0] 则不含非零段(即非零段个数为 0)。 现在我们可以对数组 A 进行如下操作:任选一个正整数 p,然后将 A 中所有小于 p 的数都变为 0。试选取一个合适的 p,使得数组 A 中的非零段个数达到最大。若输入的 A 所含非零段数已达最大值,可取 p = 1,即不对 A 做任何修改。

输入格式 从标准输入读入数据。

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

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

输出格式 输出到标准输出。

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

样例1输入 11 3 1 2 0 0 2 0 4 5 0 2 样例1输出 5 样例1解释 p = 2 时,A = [3, 0, 2, 0, 0, 2, 0, 4, 5, 0, 2],5 个非零段依次为 [3]、[2]、[2]、[4, 5] 和 [2];此时非零段个数达到最大。

样例2输入 14 5 1 20 10 10 10 10 15 10 20 1 5 10 15 样例2输出 4 样例2解释 p = 12 时,A = [0, 0, 20, 0, 0, 0, 0, 15, 0, 20, 0, 0, 0, 15],4 个非零段依次为 [20]、[15]、[20] 和 [15];此时非零段个数达到最大。

样例3输入 3 1 0 0 样例3输出 1 样例3解释 p = 1 时,A = [1, 0, 0],此时仅有 1 个非零段 [1],非零段个数达到最大。

样例4输入 3 0 0 0 样例4输出 0 样例4解释 无论 p 取何值,A 都不含有非零段,故非零段个数至多为 0。

子任务 70% 的测试数据满足 n ≤ 1000;

全部的测试数据满足 n≤5×105,且数组 A 中的每一个数均不超过 104。

#include<iostream>
#include<set>
#include<map>
#include<vector>

using namespace std;

int arr[500005];


map<int,vector<int>> m1;


int n;
set<int> s1;

int ans;
	
int main()
{
	cin >> n;

 

	for (int i = 1; i <= n; i++)
	{
		cin >> arr[i];
		s1.insert(arr[i]);

		if (m1.find(arr[i]) == m1.end())
		{
			vector <int> vtemp;
			vtemp.push_back(i);
			m1[arr[i]] = vtemp;
		}
		else
		{
			m1[arr[i]].push_back(i);
		}

	}

	if (n == 1)
	{
		cout << arr[1];
		return 0;
	}


	int www = 0;
	s1.insert(www);

	if (!*s1.rbegin())
	{
		cout << 0; return 0;
	}
	else
	{


		int sum = 0;
		




		for (auto i = s1.begin(); i != s1.end(); i++)
		{
			if (!*i)
			{
				int flag = 1;

				for (int i = 1; i <= n; i++)
				{
					if (arr[i] && flag)
					{
						sum++;
						flag = 0;
					}
					else if (!arr[i])
					{
						flag = 1;
					}
				}
			}
			else {

				for (auto w = m1[*i].begin(); w < m1[*i].end(); w++)
				{
					arr[*w] = 0;


					if (*w == 1)
					{
						if (arr[*w + 1] == 0)
						{
							sum--;
						}
					}
					else if (*w == n)
					{
						if (arr[*w - 1] == 0)
						{
							sum--;
						}
					}
					else if (arr[*w - 1] == 0 && arr[*w + 1] == 0)
					{
						sum--;
					}
					else if (arr[*w - 1] > 0 && arr[*w + 1] >0 )
					{
						sum++;
					}
					else
					{

					}

				}
			}
			

			
			//cout << "SUM=     " << sum << endl;
			ans = max(ans, sum);
		}
	}
	cout << ans;

}


举报

相关推荐

0 条评论