C. Nauuo and Cards (贪心、思维)

题目

思路:首先想能不能在原有的b中出现* * * * 1 2 3 … k,如果可以的话则利用b中原有的再添上前面的即可构成1 2 3 …n,但这个构成有一个限制,对于每一个从k往后添加k+1 k+2 … n一定要连贯着一次性达成,如果中间出现k+x没取的到,要再从前面取几个用0做缓冲,则该顺序一定会混入0,方案作废。
剩下的情况,则看一个b数组中最多需要额外多取几个才能在用到该数时能放到底部,例如 n=6 b:0 0 2 5 6 3 对于第3个元素5,想要取到其需额外先取次数 = 3 - 4(5前面会先输出4个数,所以能少额外取4个),对于第二个元素2 想要取到其需额外先取次数= 2 - 1(2前面会先输出1个数)最终结果为max(额外输出)+n

Code:

#include<iostream>
typedef long long ll;
using namespace std;
const int Max = 1e6 + 5;
int a[Max], b[Max];
int main()
{
   
	int n;cin >> n;
	for (int i = 1;i <= n;i++)cin >> a[i];
	for (int i = 1;i <= n;i++)cin >> b[i];
	int begin = 0;
	for (int i = 1;i <= n;i++)
	{
   
		if (b[i] == 1)begin = i;
		else if (begin)
		{
   
			if ((b[i] - 1) != i - begin)begin = 0;
		}
	}
	int g = 0, mi = 0;
	if (begin)g = n - begin + 1;
	int f = 0;
	if (g)
	{
   
		for (int i = 1;i + g <= n;i++)
		{
   
			if (b[i] == 0)continue;
			int v = max(0, i - (b[i] - g - 1));
			if (v > 0) f = 1;
			mi = max(mi, v);
		}
	}
	if(f==0&&g) cout << mi + n - g << endl;
	else
	{
   
		for (int i = 1;i <= n;i++)
		{
   
			if (b[i] == 0)continue;
			int v = max(0, i - (b[i] - 1));
			mi = max(mi, v);
		}
		cout << n + mi << endl;
	}
}

全部评论

相关推荐

07-03 11:02
中山大学 C++
字节刚oc,但距离九月秋招很近了有两段互联网实习,非腾讯字节。不敢赌转正,现在在纠结去还是不去如果实习俩月离职会有什么后果吗
阿城我会做到的:不去后悔一辈子,能否转正取决于ld的态度,只要他不卡,答辩就是走流程,个人觉得可以冲一把
投递字节跳动等公司8个岗位
点赞 评论 收藏
分享
06-20 17:42
东华大学 Java
凉风落木楚山秋:要是在2015,你这简历还可以月入十万,可惜现在是2025,已经跟不上版本了
我的简历长这样
点赞 评论 收藏
分享
哈哈哈哈哈哈哈哈哈哈这个世界太美好了
凉风落木楚山秋:毕业出路老师不管,你盖个章他好交差就完事了,等你盖完毕业了就不关他事情了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务