首页 > 其他分享 >「AWOI Round 2 C」数组操作?数组操作!

「AWOI Round 2 C」数组操作?数组操作!

时间:2023-08-19 09:01:22浏览次数:37  
标签:lb lc int AWOI 数组 操作 Round 翻转

「AWOI Round 2 C」数组操作?数组操作! 洛谷

题目描述

给定两个长度为 \(n\) 的数组 \(a,b\) ,将它们合并得到一个长度为 \(2\times n\) 的数组 \(c\)。

设 \(a\) 数组第 \(i\) 个元素合并后位于 \(c\) 数组第 \(lb_i\) 个位置,\(b\) 数组第 \(i\) 个元素合并后位于 \(c\) 数组第 \(lc_i\) 个位置,合并后需要满足:\(lb_1 < lb_2 < ...< lb_{n-1} < lb_n\) 且 \(lc_1 < lc_2< ...< lc_{n-1}< lc_n\),即两个数组中元素的相对位置不变。

合并过后,你需要对 \(c\) 数组进行下面操作:

  1. 变换操作:选择一个区间 \([l,r]\),对于每一个 \(i \in [l,r]\),如果 \(c_i\) 为 \(y\),则将其变成一个不同于 \(y\) 的数,否则将其变为 \(y\)。
  2. 翻转操作:选择一个区间 \([l,r]\),翻转该数组区间中的数。此操作必须刚好操作 \(z\) 次。

请输出最少需要执行多少次变换操作才能使得 \(c\) 数组中的数字都为 \(y\)。


输入格式

第一行包含三个整数 \(n,y,z\)。

第二行包含 \(n\) 个整数,代表 \(a\) 数组中的元素。

第三行包含 \(n\) 个整数,代表 \(b\) 数组中的元素。


输出格式

一个正整数,表示答案。


样例输入

5 1 1
1 1 45 1 4
1 9 1 9 810

样例输出

1

提示

对于全部数据,保证 \(0 \leqslant y,z \leqslant 10^9\),输入数据全部在 int 范围内。


由于合并出来的 \(c\) 数组不会改变数之间的相对位置,所以先研究 \(c\) 数组。

对于 \(c\) 数组分为两个部分,一部分是等于 \(y\) 的,一部分是不等于的。

如果不考虑翻转,现在所需要的变换操作就是不等于 \(y\) 的连续段的个数。

举个例子,我们知道样例一最后的 \(c\) 数组为 \({1,1,1,9,45,1,1,9,4,810}\),那么变换操作就是两次。

要让操作数尽可能小,就需要使用翻转操作,对于每一次翻转,可以把等于 \(y\) 的子段和与之相邻的不等于 \(y\) 的子段进行翻转,这样便可以把两个不等于 \(y\) 的子段拼在一起,从而减少一次操作,而 \(z\) 次翻转最多便可以减少 \(z\) 次操作。

接着考虑如何拼出一个 \(c\) 数组,根据上面的分析,很容易看出我们需要尽可能让等于 \(y\) 的子段在一起,而又不能破坏相对位置。

双指针可以搞定。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,y,z;
const int N=1e6+5;
int a[N],b[N];

signed main()
{
	scanf("%lld%lld%lld",&n,&y,&z);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	for(int i=1;i<=n;i++) scanf("%lld",&b[i]);
	int i=1,j=1;
	int flag=1,sum=0;
	while(i<=n||j<=n){
		if(flag==0) sum++;
		while((a[i]==y)==flag&&i<=n) i++;
		while((b[j]==y)==flag&&j<=n) j++;
		flag^=1;
	}
	if(!sum) return printf("0"),0;//特判,如果根本就没有不等于y的部分,直接返回0
	if(sum>z) return printf("%lld",sum-z),0;
	printf("1");
	return 0;
}

标签:lb,lc,int,AWOI,数组,操作,Round,翻转
From: https://www.cnblogs.com/HEIMOFA/p/17642027.html

相关文章

  • 线段树与树状数组
    $$\texttt{线段树}$$OI-wikiLink线段树是一种用于维护区间信息的数据结构,可以在\(O(\logn)\)的复杂度下求出一个大小为\(n\)的数组的区间信息(如区间和、区间最大值等),也可以在同样时间复杂度下实现单点修改和区间修改等操作。基本结构:......
  • Educational Codeforces Round 153 (Rated for Div. 2)
    EducationalCodeforcesRound153(RatedforDiv.2)这次的div2有点难度,当时b题思路对了,但是没有写好A题传送门A题意:给你一个只包含'('和')'的字符串,要求你将他的长度扩大一倍,并且使得所有括号匹配且组成的序列当中不能存在原序列的子序列A思路:这道题一开始写的时候没有注......
  • 代码随想录算法训练营第六天|242.有效的字母异位词 349. 两个数组的交集 202. 快乐数
     哈希表部分:哈希表,简单来说就是k-v形式查询的结构,用来快速判断一个元素是否出现集合里,如hashmap核心是哈希函数,k存哈希函数的值,找的时候找查询项的哈希函数值就行,返回v 出现哈希碰撞的时候,查找的流程怎么走呢?(*存疑,之后查一下) 类型:数组+集合set(set、multiset、unordered......
  • JavaScript中的析构对象,析构数组与展开运算符
    前言这些是JavaScript中重要的编程思想,这些析构对象,析构函数与展开运算符很重要这块内容不怎么难,纯属一些语法,但是在所谓的函数式编程,以及React中却是广泛使用的逆向思维,之前是怎么构造,而现在让你如何展开,获取里面的内容!!逆向思维,之前是怎么构造,而现在让你如何展开,获取里面的内......
  • 「AWOI Round 2 A」最大和
    嘿嘿,来水题解了。题目链接。题目简化给你一个数,从它的个位到最高位进行操作,对于其每一位,你可以选择让他增加\(1\),减少\(1\)(如果当前位是\(0\),减\(1\)后会退位)或者不变。分析要使每一位的总和最大,我们可以对每一位进行判断。如果当前位不是\(0\)和\(9\),那么显然要......
  • Codeforces Round 881 (Div. 3)
    比赛链接:https://codeforces.com/contest/1843A.SashaandArrayColoring题意:一个数组,可以任意分成任意组,每组的贡献是组最大值减最小值,求最大总贡献思路:一组内只有最大值和最小值有用,所以每组只由两个数组成即可,用贪心的思路,依次取出原数组的最大和最小值成组即可B.LongL......
  • 常用数组方法
    1.push()末尾添加数据2.pop()末尾出删除数据3.unshift()头部添加数据4.shift()头部删除数据5.reverse()翻转数组6.sort()排序7.splice() 截取数组8.concat()合并数组9.join()数组转字符串10.slice()截取数组的一部分数据11.indexOf从左检查数组中有没有这个数值12.lastInde......
  • C++快速入门 第十讲:复杂的数据类型——指针和数组
    计算机是把数组以一组连续的内存块保存的。数组的第一个元素的地址为该数组的基地址。实例1:数组元素地址打印1#include<iostream>23usingnamespacestd;45intmain()6{7constunsignedshortITEMS=5;8intintArray[ITEMS]={1,2,3,4,5}......
  • js筛选数组排除多个多个不符合项
    constarr=[{label:'2',value:'2'},{label:'1',value:'1'},{label:'3',value:'3'}]//把value=1和value=2的数据筛掉letnewArr=arr.filter(opt=>......
  • 笔记整理--C语言--数组指针和指针数组的区别 - hongcha_717 - 博客园——转载
    【转载】:原文http://www.cnblogs.com/hongcha717/archive/2010/10/24/1859780.html数组指针和指针数组的区别数组指针(也称行指针)定义int(*p)[n];()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个......