CodeCraft-22 and Codeforces Round #795 (Div. 2)

news2024/11/20 15:23:27

A. Beat The Odds

题目链接: Problem - A - Codeforces

样例输入:

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

样例输出:

1
0

题意:给定一个长度为n的数组,我们可以对这个数组进行操作,每次操作可以删除一个数,问至少操作多少次可以使得数组中任意两个相邻的数的和是偶数。

分析:只有奇数+奇数或者偶数+偶数才能等于偶数,所以题目就是问至少要删除多少个数才能使得数组中的数都是奇数或者都是偶数,所以我们只需要统计一下原来奇数和偶数的个数,输出较小值即可。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n,t;
		scanf("%d",&n);
		int ans=0;
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&t);
			if(t&1) ans++;
		}
		printf("%d\n",min(ans,n-ans));
	}
	return 0;
} 

B. Shoe Shuffling

题目链接:Problem - B - Codeforces

样例输入: 

2
5
1 1 1 1 1
6
3 6 8 13 15 21

样例输出:

5 1 2 3 4 
-1

题意:给定一个长度为n的数组a[],让我们构造一个1~n的排列p[],使得p[i]!=i且a[p[i]]>=a[i].如果存在这样的排列就输出排列,否则输出-1.

分析:假如a[l~r]是相同的,如果l!=r,那么我们就可以令p[l]=r,r[l+1]=l,p[l+2]=l+1,……,p[r]=r-1.按照值相同的区间进行分段确定序列,如果l=r,那么就无解。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
int a[100010],p[100010];
int main()
{
	int T;
	cin>>T;
	int n;
	while(T--)
	{
		bool flag=true;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
			scanf("%d",&a[i]);
		for(int i=1;i<=n;i++)
		{
			int l=i,r=i+1;
			while(r<=n&&a[r]==a[l]) r++;
			r--;
			if(l==r)
			{
				flag=false;
				break;
			}
			p[l]=r;
			for(int j=l+1;j<=r;j++)
				p[j]=j-1;
			i=r;
		}
		if(flag)
		{
			for(int i=1;i<=n;i++)
				printf("%d ",p[i]);
			puts("");
		}
		else
			puts("-1");
	}
	return 0;
}

C. Sum of Substrings

题目链接:Problem - C - Codeforces

 样例输入:

3
4 0
1010
7 1
0010100
5 2
00110

 样例输出:

21
22
12

题意:给定一个长度为n的01串,定义di=si si+1组成的十进制数,f(s)=d1+d2+……+d(n-1)。我们可以对这个01串进行操作,每次操作可以交换两个相邻的数,问操作次数不大于k的情况下f(s)的最小值为多少。

分析:通过考虑每一位1的贡献可以发现,只要是1不位于两端,那么他的贡献就是11,无所谓1和谁相邻。所以我们要想减小贡献那么只能考虑把1移至两端,如果把1移至最右端那么1只能贡献1,如果把1移至最左端那么1只能贡献10,所以我们优先考虑把1移至最右端。然后接下来就是根据1的个数和位置来进行分情况讨论了,这个比较简单,细节见代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
const int N=2e5+10;
char s[N];
int main()
{
	int T;
	cin>>T;
	int ans=0;
	while(T--)
	{
		int n,k;
		int ans=0;
		scanf("%d%d%s",&n,&k,s+1);
		for(int i=2;i<=n;i++)
			ans+=(s[i-1]-'0')*10+s[i]-'0';
		int idl=1,idr=n;
		while(idl<=n&&s[idl]=='0') idl++;
		while(idr>=1&&s[idr]=='0') idr--;
		if(idr<1||idl>n)//代表没有1 
		{
			printf("%d\n",ans);
		}
		else if(idr==idl)//代表只有一个1
		{
			int cntr=n-idr;
			int cntl=idl-1;
			if(cntr<=k&&cntr!=0)
			{
				if(cntr==n-1)//说明唯一的1位于最左端 
					ans-=9;
				else
					ans-=10; 
			}
			else if(cntl<=k&&cntl!=0&&cntl!=n-1)
				ans-=1;
			printf("%d\n",ans);
		}
		else
		{
			int cntr=n-idr;
			int cntl=idl-1;
			if(cntr<=k&&cntr!=0)
			{
				k-=cntr;
				ans-=10;
			}
			if(cntl<=k&&cntl!=0)
				ans-=1;
			printf("%d\n",ans);
		}
	}
	
	return 0;
}

D. Max GEQ Sum

题目链接:Problem - D - Codeforces

样例输入:

3
4
-1 1 -1 2
5
-1 2 -3 2 -1
3
2 3 -1

样例输出:

YES
YES
NO

题意:给定一个长度为n的数组,如果该数组满足对于任意的<=i<=j<=n,都有max(a[i~j])>=a[i]+a[i+1]+……+a[j],那么就输出YES,否则输出NO.

分析:我们发现区间max的值最多只有n种情况,所以我们可以枚举每一个值作为区间最大值的区间,从该区间种找出一段包含最大值所在位置的区间使得该区间和最大,也就是最大化不等式右边的值,如果最大值都满足,那么该区间内的所有数都满足。比如说我们当前枚举a[i]为最大值,我们找到了l[i],r[i]分别是以a[i]为最大值的区间的最左边和最右边,那么我们随便从[l[i],i]中选择一个数作为区间左边界,然后从[i,r[i]]中选择一个数作为区间右边界,即满足区间最大值为a[i]。关键是我们现在就是要求解所有区间中的和的最大值。既然一定要包含a[i]我们可以分成两部分来求,一部分是在区间[l[i],i]找到一个p使得满足a[p]+a[p+1]+……+a[i]值最大,在区间[i+1,r[i]]中找到一个q使得满足a[i+1]+a[i+2]+……+a[q]值最大,区间加和我们可以用前缀和来优化,至于找最大值和最小值问题我们可以用ST表来解决。要想找到以某个数为最大值的左右区间的边界,我们可以直接用单调栈求解。

细节见代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
const int N=2e5+6;
long long s[N],fx[N][32],fn[N][32];
int l[N],r[N],st[N],tt;
long long find_max(int L,int R)
{
	int len=(int)log2(R-L+1);
	return max(fx[L][len],fx[R+1-(1<<len)][len]);
}
long long find_min(int L,int R)
{
	int len=(int)log2(R-L+1);
	return min(fn[L][len],fn[R+1-(1<<len)][len]);
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
			scanf("%lld",&s[i]);
		tt=0;
		for(int i=1;i<=n;i++)
		{
			while(tt&&s[st[tt]]<=s[i]) tt--;
			if(tt) l[i]=st[tt]+1;
			else l[i]=1;
			st[++tt]=i;
		}
		tt=0;
		for(int i=n;i>=1;i--)
		{
			while(tt&&s[st[tt]]<=s[i]) tt--;
			if(tt) r[i]=st[tt]-1;
			else r[i]=n;
			st[++tt]=i;
		}
		tt=0;
		for(int i=2;i<=n;i++)//前缀和 
			s[i]+=s[i-1];
		for(int i=0;i<=n;i++)
			fx[i][0]=fn[i][0]=s[i];
		for(int len=1;len<=30;len++)
		for(int l=0;l-1+(1<<len)<=n;l++)
		{
			fx[l][len]=max(fx[l][len-1],fx[l+(1<<(len-1))][len-1]);
			fn[l][len]=min(fn[l][len-1],fn[l+(1<<(len-1))][len-1]);
		}
		bool flag=true;
		for(int i=1;i<=n;i++)//枚举最大值
		{
			long long mx=s[i]-s[i-1];
			long long lsum=s[i]-find_min(l[i]-1,i-1);
			long long rsum=max(find_max(min(i+1,r[i]),r[i])-s[i],0ll);//区间[i+1,r[i]]的数不是必选的,可以不选 
			if(rsum+lsum>mx)
			{
				flag=false;
				break;
			}
		}
		if(flag) puts("YES");
		else puts("NO");
	}
	return 0;
}

E. Number of Groups

题目链接:Problem - E - Codeforces

样例输入: 

2
5
0 0 5
1 2 12
0 4 7
1 9 16
0 13 19
3
1 0 1
1 1 2
0 3 4

样例输出:

2
3

题意:给定n条线段,每条线段有三个特征,一个是颜色c,一个是左端点l,另一个是右端点r,如果两条线段颜色不同且存在交集,那么他们就可以放在一组,假如线段i和线段j可以分为一组,线段j和线段k可以分为一组,那么线段i,j,j就可以分为一组。现在问这n条线段至少会被分为几组。

分析:通过题意描述我们可以发现分组具有传递性,显然是可以用并查集维护的,我们可以单独考虑每条红色线段和每条蓝色线段是否可以分为一组,这样总的复杂度就是O(n^2),显然是不行的。所以我们必须要对这个考虑优化,我们可以考虑把每条红色线段仅与与他相交且右端点位置最远的一条蓝色线段建立联系,这样总的连接数就是O(n),于是我们就可以把一条线段看成两个点,左端点看成入点,右端点看成出点,按照位置对点进行从小到大排序,相同位置按照入点在前的顺序进行排列,当遍历到左端点时,就把这条线段加入进集合,并找到与这条线段颜色不同且右端点最远的一条线段并建立联系,当遍历到右端点时就直接把这条线段删除即可。这样我们就可以建立与每条红色线段相关的蓝色线段。但是我们发现一个问题,就是我们只有红色线段之间的关系,并没有蓝色线段之间的关系,所以这样维护显然是会出问题的,我们需要维护蓝色线段之间的关系,所以当我们加入一个红色线段时,先看一下当前集合中的蓝色线段有多少,然后分别与当前的红色线段建立联系,每建立一次联系就把这个蓝色线段从集合中删除,直至剩一个右端点最大的,因为这些被删除的蓝色线段和最后剩余的蓝色线段都与当前的红色线段建立了联系,所以这些蓝色线段也通过并查集建立了联系。但是处在集合中的蓝色线段说明还没遇到其右端点,当遇到其右端点时还会被删除一次,但是不影响,顶多算是无效操作,按照这样的方法我们就能在最多建立n次联系的基础上找到他们的关系了。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<set>
using namespace std;
typedef pair<int,int> PII;
const int N=2e5+10;
int c[N],l[N],r[N],fu[N];
int find(int x)
{
	if(x!=fu[x]) return fu[x]=find(fu[x]);
	return x;
}
void merge(int x,int y)
{
	int fx=find(x),fy=find(y);
	if(fx!=fy) fu[fx]=fy;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		scanf("%d",&n);
		priority_queue<PII,vector<PII>,greater<PII> >q;
		for(int i=1;i<=n;i++)
		{
			scanf("%d%d%d",&c[i],&l[i],&r[i]);
			fu[i]=i;
			q.push({l[i],-i});
			q.push({r[i],i});
		}
		set<PII> s[2];
		while(!q.empty())
		{
			PII t=q.top();
			q.pop();
			if(t.second>0)//区间右端点 
				s[c[t.second]].erase({r[t.second],t.second});
			else//区间左端点 
			{
				int id=t.second*(-1);
				s[c[id]].insert({r[id],id});
				while(s[1^c[id]].size()>1)//保证相同颜色线段可以合并 
				{
					merge(id,s[1^c[id]].begin()->second);
					s[1^c[id]].erase(s[1^c[id]].begin());
				}
				if(s[1^c[id]].size()==1) merge(id,s[1^c[id]].begin()->second);
			}
		}
		int ans=0;
		for(int i=1;i<=n;i++)
			if(find(i)==i) ans++;
		printf("%d\n",ans);
	}
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/156744.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机防勒索病毒之系统主机加固篇

​ 近年来&#xff0c;计算机以及互联网应用在中国得到普及和发展&#xff0c;已经深入到社会每个角落&#xff0c;政府&#xff0c;经济&#xff0c;军事&#xff0c;社会&#xff0c;文化和人们生活等各方面都越来越依赖于计算机和网络&#xff0c;电子政务&#xff0c;无纸办…

如何把WPS转换成PDF格式?新手也能轻松学会的方法

WPS文件是我们工作中必不可少的&#xff0c;它可以编辑文本、记录数据、展示文档等等&#xff0c;都能更好的帮我们处理工作&#xff0c;不过有的时候WPS文件在不同设备上打开可能会出现格式错误或者乱码等一系列的问题&#xff0c;这时候我们就可以将WPS文件转换成PDF文件&…

[Leetcode] 传递信息(有向图路径)

小朋友 A 在和 ta 的小伙伴们玩传信息游戏&#xff0c;游戏规则如下&#xff1a;有 n 名玩家&#xff0c;所有玩家编号分别为 0 &#xff5e; n-1&#xff0c;其中小朋友 A 的编号为 0每个玩家都有固定的若干个可传信息的其他玩家&#xff08;也可能没有&#xff09;。传信息的…

Python数据分析之Pandas

文章目录前言一、输入输出1.1 txt1.2 csv1.3 excel1.4 json1.5 sql1.6 html1.7 latex二、数据结构2.1 一维数据 Series2.2 二维数据 DataFrame2.2.1 数据查看2.2.2 数据遍历2.2.3 数据选取2.2.4 数据处理2.2.5 数据统计2.3 索引对象 Index2.4 时间戳 TimeStamp三、窗口函数3.1 …

【每日一题】【LeetCode】【第十天】只出现一次的数字

解决之路 题目描述 测试案例&#xff08;部分&#xff09; 第一次 和昨天的题目有点类似&#xff0c;昨天是找重复&#xff0c;今天是找不重复。那直接按昨天第二次思路来写这次的代码。 class Solution(object):def singleNumber(self, nums):nums.sort()for i in range(l…

在线计算lncRNA-mRNA共表达相关系数,并使用cytoscape绘制共表达网络图

长链非编码RNA(Long noncoding RNA)是一类长度大于200 nt&#xff0c;不编码蛋白质的RNA。LncRNA的功能多样&#xff0c;如图1所示&#xff0c;A&#xff1a;充当蛋白质和染色质的连接因子&#xff0c;引起染色质重构&#xff08;chromatin remodeling&#xff09;&#xff1b;…

内存函数细节及实现

1、memcpy内存拷贝 不仅可以拷贝&#xff0c;还可以拷贝整型、结构体等&#xff0c;因为直接拷贝了内存。 因为不知道要拷贝的类型是什么&#xff0c;所以都用void*来接收。num是拷贝的字节数 拷贝时可任意选择dest&#xff0c;src&#xff0c;以及字节数。返回void*类型的指…

01什么是FPGA?

FPGA 是一种硬件可重构的体系结构。它的英文全称是Field Programmable Gate Array&#xff0c;中文名是现场可编程门阵列。 FPGA就是一个可以通过编程来改变内部结构的芯片&#xff0c;FPGA常年来被用作专用芯片&#xff08;ASIC&#xff09;的小批量替代品&#xff0c; 同时也…

PMP考试流程是怎么样的?

别的问题我可能不太了解&#xff0c;但考试流程我绝对是非常清楚了&#xff01;话不多说&#xff0c;直接放流程给到大家&#xff0c;好歹通过考试了&#xff0c;基本的情况还是能给大家讲解一下的。希望能够给有需要的同学提供点帮助。 先把考试的流程看仔细了&#xff0c;之…

核心乐理---音程名称

定义 音程是连个音之间的距离&#xff0c;是音乐中的距离&#xff0c;可以便于我们描述音符间的距离&#xff0c;便于与他人进行沟通交流。 就好像是厘米&#xff0c;米这些这些物理中的长度单位一样 度 度是音程的单位。 从一个音的名字念到另一个音的名字&#xff0c;一共念…

瑞幸“复制”拼多多

&#xff08;图片来源于网络&#xff0c;侵删&#xff09; 来源 | 螳螂观察 文 | 叶小安 在电商界&#xff0c;拼多多杀出阿里京东围剿重围&#xff0c;奠定现今电商行业“猫狗拼”三分天下的格局&#xff0c;这是多少后辈们参考的范本。 在咖啡界&#xff0c;瑞幸凭借低价…

ESP32基于Arduino框架,SD卡+MAX98357模块+MP3播放器

ESP32基于Arduino框架&#xff0c;SD卡MAX98357模块MP3播放器&#x1f3ac;原创作者的制作教程讲解以及源码&#xff1a; 35 ESP32之简单的完整功能SD卡MP3播放器的制作讲解&#xff08;ESP32-audioI2S库介绍&#xff09;- 基于Arduino链接&#xff1a;https://pan.baidu.com/s…

黑产系列02-黑产画像

黑产无利不起早&#xff0c;在利益的驱动下黑产几乎是屡禁不止&#xff0c;作为风控从业人员我们需要全方位的了解黑产&#xff0c;了解我们的对手&#xff0c;才能知己知彼&#xff0c;接下来我将结合我多年风控经验以及查阅的相关的资源&#xff0c;全方位介绍下黑产以及他们…

matplot绘制动图

import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation import numpy as np plt.rcParams[axes.unicode_minus] False plt.rcParams[font.sans-serif] SimHei# 准备数据 x np.linspace(0,3*np.pi,100) y1 np.sin(x) y2 np.cos(x)#创建画布和子图 …

Python用yield from 实现异步协程爬虫

文章目录一、什么是yield二、yield于列表的区别三、yield from 实现协程一、什么是yield 如果还没有怎么用过的话&#xff0c;直接把yield看做成一种特殊的return&#xff08;PS&#xff1a;本质 generator&#xff08;生成器&#xff09;&#xff09; return是返回一个值然后…

Python网络编程中getservbyport和getservbyname函数的用法

在Python的网络编程中&#xff0c;getservbyport()函数和getservbyname()函数是socket模块中的两个函数&#xff0c;因此在使用这两个函数时&#xff0c;需要导入socket模块。1 getservbyname()函数getservbyname()函数的作用是通过指定服务的名称获取该服务对应的端口号。相关…

BI工具+方案,这是要将大数据分析包了的节奏啊

BI工具是一个为企业提供大数据智能可视化分析功能板块的平台。虽然它提供了包括智能钻取、内存行列计算、多维动态分析等多种智能数据分析功能板块&#xff0c;但工具毕竟是工具&#xff0c;要真正地为企业所用&#xff0c;还需要针对企业的业务发展情况、数据分析需求等制定数…

用ode45解一个带有积分的微分方程(integro-differential equations)

一、问题提出: 这个方程来源于mathworks的论坛 l 这种方程叫 integro-differential equations ,大致是带有 integral term的微分方程。积分肯定是定积分,这类方程有的是变上限的积分,上下限是x或者其他微分的函数。 按照惯例,先分析。积分区间是0-1,x是自变量,y是应…

2022年终总结——工作第五年

2022是本命年&#xff0c;对我来说今年勉强可以算得上是一切顺利吧。 前几年的年终总结 先验收下去年的期望吧 去年的期望还是挺多的嗷&#x1f643; 1、关于订婚和云南一周游 ✅ 今年大概2月底开始上海疫情开始变得很严重&#xff0c;然后就是漫长的三个月封控&#xff0c;…

1.1.3 java学习的环境准备

文章目录1 相关文件准备及下载1.1 JDK下载1.2 开发工具下载1.2.1 eclipse1.2.2 idea2 JDK安装及配置2.1 JDK配置方法一2.2 JDK配置方法二3 eclipse软件安装及配置4 JDK JRE JVM解释&#xff1a;5 关于手写代码1 相关文件准备及下载 1.1 JDK下载 Oracle公司为常见的计算机系统…