CodeForces-Grouping Increases

题目

前言

首先着重讲下我的思路先:

8 2 3 1 1 7 4 3

我是定义一个now=a[i-1],每次进来就对其比较从而找出一个下降的序列,然后认为(很理想)这个序列是贡献为0,但是会出意外,这样比较是肯定会出错的,贡献怎么可能为0,然后又改成比较队尾元素了,这样做就没意义了

8 7 6 5 4 3 2 1 5 7 4 7 3 7 2 7

把8 7 6 5 4 3 2 1读进去了又如何,

后面的5 7 4 7 3 7 2 7 没读进去 纳入另一个队列,这样算的贡献为2,

实际答案为1.这就是我的思路出错地方然后做不出来

思路

我在b站关注的up主下面评论区看到某人说了这句话 我觉得很有启发

说的很对,就是要两个盒子,一大一小,我看了这句话写了一段代码

void solve()
{
	vector<int>v,v1;
	int n;
	cin>>n;
	int a[200005];
	v.push_back(99999);
	v1.push_back(99999-1);
	long long ans=0;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		int sum1=v.back();
		int sum2=v1.back();
		cout<<sum1<<"   "<<sum2<<endl;
		if(a[i]<=sum1&&a[i]<=sum2)
		{
			if(sum1>sum2)v1.push_back(a[i]);
			else v.push_back(a[i]);
			//以上情况未考虑想等
		}
		//这种写法没有定义大小二盒子 导致其中一个盒子永远都是9999/
		//或者说如果碰到了序列最大值以后都不会再push进去了
		// 都大的时候6 8 9  去更小的 都小的时候6 8 5 去更小的
		//大于其中一个的时候 比如 8 5 6 去8那里  等于我后面思考
		// 6 8 8 
	else if(a[i]>sum1&&a[i]>sum2)
		{
			if(sum1>sum2)v1.push_back(a[i]),ans++;
			else v.push_back(a[i]),ans++;
			//以上情况未考虑想等
		}
	else if(a[i]>sum1&&a[i]<=sum2)v.push_back(a[i]);
	else if(a[i]<=sum1&&a[i]>sum2)v1.push_back(a[i]);		
	}
	cout<<ans<<endl;
	return ;
}

错误在于我维护了两个盒子

没有说明哪个大哪个小 于是乎

另一个盒子原因都不会被更新或者说更新了遇到最大的后就不会更新了

比如样例给的8 2 3 1 1 7 4 3

都没更新过 所以要两个 一大一小

代码实现

#include<iostream>
#include<vector>
using namespace std;
void solve()
{
	vector<int>v1,v2;
	int n;
	cin>>n;
	v1.push_back(999999);
	v2.push_back(999999);
	int a;
	for(int i=1;i<=n;i++)
	{
	    cin>>a;
		bool flag1=a<=v1.back();
		bool flag2=a<=v2.back();
		if(flag1==flag2)
		{
			if(v1.back()>v2.back())v2.push_back(a);
			else v1.push_back(a);
		}
		else if(a<=v1.back())v1.push_back(a);
		else v2.push_back(a);
		//这样的写法值得学习 以及a[i]>a[i-1]
		//有效防止了v1.size-1时的特判
	}
	long long ans=0;
    for(int i=1;i<v1.size();i++)if(v1[i]>v1[i-1])ans++;
	for(int i=1;i<v2.size();i++)if(v2[i]>v2[i-1])ans++;
	cout<<ans<<endl;
	return ;
}
int main()
{
	int t;
	cin>>t;
	while(t--)solve();
	
	return 0;
}



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

其中要学习下

for(int i=1;i<v1.size();i++)if(v1[i]>v1[i-1])ans++;
for(int i=1;i<v2.size();i++)if(v2[i]>v2[i-1])ans++;

没有想到vector数组还能这么被访问还是自己太笨不懂得变通

这个问题我之前题解也说了很多次了老是比赛写不出来,


然后就是这个i>i-1,有效防止了如果写成i+1,然后溢出的特判。

这一点很好。

posted @ 2025-04-16 20:25  LteShuai  阅读(9)  评论(0)    收藏  举报