Codeforces Round 913 (Div. 3)补题

 Rook

题目大意:我们给定一个棋盘(如下图),棋盘上有一个车,问车可以到的位置,任意顺序输出即可。

思路:输出车的行列中非它本身的点即可。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		char s[3];
		scanf("%s",s);
		for(int i=1;i<=8;i++)
		{
			if((s[1]-'0')!=i)
			printf("%c%d\n",s[0],i);
		}
		for(int i=0;i<8;i++)
		{
			if('a'+i!=s[0]) printf("%c%c\n",'a'+i,s[1]);
		}
	}
}

 YetnotherrokenKeoard

 题目大意:我们需要输入一串字符,但是键盘上"b"按键出问题了,我们按下"b"时会删除最后一个小写字母,按下"B"时,会删除最后一个大写字母,如果待删除的字母不存在那么就不进行任何操作,我们需要输出最后的字串。

思路:这题的核心在于考虑最后哪些结果出现在答案中,因为涉及到大写和小写,而且还要分开删除,那么我们直接用两个容器来装访问到的字母,然后对应进行删除即可。最后输出只用按顺序输出即可,那么这个顺序是怎样的呢?我们记录下它们在原字串中的下标,然后按顺序输出即可(这里可以用下双指针)

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		string s;
		cin>>s;
		vector<pair<char,int>>d,x;
		for(int i=0;i<s.size();i++)
		{
			if(s[i]=='B')
			{
				if(d.size()) d.pop_back();
				continue;
			}
			if(s[i]=='b')
			{
				if(x.size())x.pop_back();
				continue;
			}
			if('A'<=s[i]&&s[i]<='Z') d.push_back({s[i],i});
			if('a'<=s[i]&&s[i]<='z') x.push_back({s[i],i});
		}
		int i=0,j=0;
		while(i<d.size()&&j<x.size())
		{
			if(d[i].second<x[j].second) cout<<d[i].first,i++;
			else cout<<x[j].first,j++;
		}
		while(i<d.size()) cout<<d[i].first,i++;
		while(j<x.size())cout<<x[j].first,j++;
		cout<<endl;
	}
}

Removal of Unattractive Pairs

题目大意:有一串字符串,我们可以将相邻两个不同的字符删除,问我们删除尽可能多次后,剩下的字符串的长度最短是多少。

思路:我们可以发现,最后就算剩下也只能剩下一种字符,一旦有两种及以上字符剩下,那么必然存在两个相异的字符相邻,那么就必须删除。所以我们只用去统计每种字符出现的个数,并记录个数的最大值,如果最大值小于等于n/2那么 一定是可以全部消掉的,否则,最多的那个字母就会剩下,另外,要注意n为奇数,那么最终不管mx是多少,都会剩下一个字符,因为没有能跟它配对的了。

#include<bits/stdc++.h>
using namespace std;
char s[200010];
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		scanf("%d",&n);
		scanf("%s",s);
		map<char,int>mp;
		int mx=0;
		for(int i=0;i<n;i++) mp[s[i]]++,mx=max(mp[s[i]],mx);
		if(n%2)
		{
			if(mx>n/2+1) mx -= (n-mx);
			else mx=1;
		}
		else
		{
			if(mx>n/2) mx -= (n-mx);
			else mx=0;
		}
		printf("%d\n",mx);
	}
}

Jumping Through Segments

题目大意:有n个区间,标号分别为1,2,..,n,它们都是x轴上的区间,我们初始在位置0,每次最多移动距离k,现在需要找到一个最小的k,使得第i次移动落在区间i内。

思路:这道题虽然一眼二分,但是check()很容易出差错,因为惯性思维还是考虑移动多少落在哪个点,然后就会去考虑每步怎么移动才是最优的。但是这是没必要的事情,这和另外一个题有点像(Absolute Sorting),不能考虑单点,需要考虑每次移动会落在哪个区间内。那么我们就从这个角度来考虑,首先每次的移动肯定要落在[l[i],r[i]]区间内部,在这个区间之外就没必要移动了,其次,我们假设上一次落在区间[L,R]内,那么能移动到的区间最多只能是[L-x,R+x](假设每次可以移动的最远距离是x),那么我们实际上这一次移动合法且有效的区间就是两个区间取交集,那么这一次移动的落点区间就找出来了。判否的条件就是这两个区间没有交集,至此问题解决。

#include<bits/stdc++.h>
using namespace std;
int l[200010],r[200010];
int n;
bool check(int x)
{
	int L=0,R=0;
	for(int i=1;i<=n;i++)
	{                            
		L=max(l[i],L-x);
		R=min(r[i],R+x);
		if(L>R) return false;
	}
	return true;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		int mx=0;
		for(int i=1;i<=n;i++) scanf("%d%d",&l[i],&r[i]),mx=max(mx,r[i]);
		int l=0,r=mx;
		while(l<r)
		{
			int mid=(l+r)/2;
			if(check(mid)) r=mid;
			else l=mid+1;
		}
		printf("%d\n",l);
	}
}

ps:既然本题和Absolute Sorting比较像,那么我们就来顺便复习一下这道题。

题目大意:给定一个数组a[],我们需要对a[]进行排序,但是我们能进行的操作就是选定一个x,然后对于所有的ai,用|ai-x|替换ai,找出最小的x或者报告x不存在输出-1.

思路:这道题首先要明确|ai-x|表示的是距离(上次卡在这个地方,竟然没卡在从区间的角度考虑,还是得卡住才能影响深刻嘞,不过上次比较幸运最后想到了这个,直接把思路顺出来了),然后我们替换表示用距离去代替它们,所以很显然如果如果a[i]<a[i+1]那么选的x肯定要里a[i]更近,然后替换完两者的大小关系不会变,如果a[i]>a[i+1]那么两者的大小关系要改一下,那么就是选的x要离a[i+1]更近。这道题最开始也是想的考虑单点,即在最优策略下x选在哪个点,然后对其他的情况是否成立,但是很显然这个最优策略就很难评,所以后来想到去遍历确定x的合法区间,这个题甚至连二分都不用。因为这个题不需要知道具体x的值(而且这个题用二分还写不了,因为就算我们二分出x的值,判断对于所有的a[i]改变后是否成立,但是如果不成立,x该变大还是变小,我们并没有办法确定),上个题是不需要知道具体的区间落在哪里,但是转移需要x,所以需要二分x的值。但是它们的共同点都是去考虑合法区间而非单点。

Good Triples

题目大意:我们给定一个非负整数n,需要把n拆成3个数a,b,c,要求n=a+b+c,定义digit(n)为n的数位和,同时还要求:digit(n)=digit(a)+digit(b)+digit(c),求这样的三元组有多少个,同时规定[a,b,c]与[b,a,c]是两个三元组。

思路:我们首先来看,要使和和数位和都相等,那么a+b+c得是不进位直接加的,这样才能保证满足条件。那么就是对每一位上的数字进行拆解,那么拆解之后如何拼起来呢?我们可以发现,如果只将目光聚焦在每一位上的时候,那就相当于将当前这个数的这一组拆解放入3个容器,问有多少种放法,然后有多少组拆解,把它们的方法求和,就得到这一位能产生的不同情况,然后我们注意到,总共有若干位,将每一位的放法都求出来然后相乘即可。另外注意到,每一位上的数字都是0-9的,那么我们可以预处理一个数组出来,数值比较少,可以直接手算:

int a[]={1,3,6,10,15,21,28,36,45,55};

 那么问题就解决了。讲真这个题实际比D简单,如果D的那个点卡住的话,真不如先写E。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a[]={1,3,6,10,15,21,28,36,45,55};
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		scanf("%d",&n);
		long long ans=1;
		if(n==0) ans=1ll;
		else
		{
			while(n)
			{
				int d=n%10;
				ans *= (long long)a[d];
				n/=10;
			}
		}
		printf("%lld\n",ans);
	}
}

Shift and Reverse

题目大意:现有一个大小为n的数组a[],我们可以进行如下两个操作任意多次:

1.将末尾元素移到开头

2.将数组反转

我们最后需要使a[]变成非递减数组,问最少需要进行多少次操作,如果不管怎么操作都得不到就输出-1。

思路:我们来分析一下操作的实际意义。

我们将操作1命名为z,操作2命名为f。(一下描述中f或者z可能表示连着这么操作很多次)

对于数组:a[1]a[2]a[3]...a[n-2]a[n-1]a[n]:

z:a[n]a[1]a[2]a[3]...a[n-2]a[n-1]

f:a[n]a[n-1]a[n-2]...a[3]a[2]a[1]

fz:a[n]a[n-1]a[n-2]...a[3]a[2]a[1]->a[2]a[1]a[n]a[n-1]a[n-2]...a[3]

zf:a[n-1]a[n]a[1]a[2]a[3]...a[n-2]->a[n-2]...a[3]a[2]a[1]a[n]a[n-1]

fzf:a[n]a[n-1]a[n-2]...a[3]a[2]a[1]->a[2]a[1]a[n]a[n-1]a[n-2]...a[3]->

     a[3]...a[n-2]a[n-1]a[n]a[1]a[2]

zfz:a[n-1]a[n]a[1]a[2]a[3]...a[n-2]->a[n-2]...a[3]a[2]a[1]a[n]a[n-1]->

      a[n-1]a[n-2]...a[3]a[2]a[1]a[n](相当于zf中的z少执行几次而已,故而没有存在的必要)

fzfz:a[n]a[n-1]a[n-2]...a[3]a[2]a[1]->a[2]a[1]a[n]a[n-1]a[n-2]...a[3]->

     a[3]...a[n-2]a[n-1]a[n]a[1]a[2]->a[2]a[3]...a[n-2]a[n-1]a[n]a[1]

(相当于fzf中的z少执行几次而已,也没有存在的必要,后面就不用再讨论了,延伸不下去了。)

那么实际有效的只有z,f,fz,zf,fzf这几个操作,我们就对每个操作执行到底,看看能不能生成目标数组,如果可以取操作最小值,否则输出-1。另外记录一下,如果数组本身单增,那么输出0,单减输出1.

#include<bits/stdc++.h>
using namespace std;
int a[100010],b[100010],tmp[100010];
int n;
int z()
{
	//不管怎样都是转
	int c=a[1],idx=n+1;
	for(int i=n;i>=1;i--)
	{
		if(a[i]<=c) c=a[i],idx=i;
		else break;
	}
	int j=0;
	for(int i=idx;i<=n;i++) tmp[++j]=a[i];
	for(int i=1;i<idx;i++) tmp[++j]=a[i];
	//判增
	c=tmp[1];
		idx=n-idx+1;
	for(int i=2;i<=n;i++)
	{
		if(tmp[i]<c) 
		{
			idx=-1;
			break;
		}
		c=tmp[i];
	}
	return idx;
}
int zf()
{
	//先转成单减的再反
	int c=a[1],idx=n+1;
	for(int i=n;i>=1;i--)
	{
		if(a[i]>=c) c=a[i],idx=i;
		else break;
	}
	int j=0;
	for(int i=idx;i<=n;i++) tmp[++j]=a[i];
	for(int i=1;i<idx;i++) tmp[++j]=a[i];
	reverse(tmp+1,tmp+1+n);
	//判增
	c=tmp[1];
		idx=n-idx+1;
		idx += 1;
	for(int i=2;i<=n;i++)
	{
		if(tmp[i]<c) 
		{
			idx=-1;
			break;
		}
		c=tmp[i];
	}
	return idx;
}
int fz()
{
	int c=b[1],idx=n+1;
	for(int i=n;i>=1;i--)
	{
		if(b[i]<=c) c=b[i],idx=i;
		else break;
	}
	int j=0;
	for(int i=idx;i<=n;i++) tmp[++j]=b[i];
	for(int i=1;i<idx;i++) tmp[++j]=b[i];
	//判增
	c=tmp[1];
		idx=n-idx+1;
		idx+=1;
	for(int i=2;i<=n;i++)
	{
		if(tmp[i]<c) 
		{
			idx=-1;
			break;
		}
		c=tmp[i];
	}
	return idx;
}
int fzf()
{
	reverse(a+1,a+1+n);
	int c=a[1],idx=n+1;
	for(int i=n;i>=1;i--)
	{
		if(a[i]>=c) c=a[i],idx=i;
		else break;
	}
	int j=0;
	for(int i=idx;i<=n;i++) tmp[++j]=a[i];
	for(int i=1;i<idx;i++) tmp[++j]=a[i];
	reverse(tmp+1,tmp+1+n);
	//判增
	idx=n-idx+1;
	idx += 2;
	c=tmp[1];
	for(int i=2;i<=n;i++)
	{
		if(tmp[i]<c) 
		{
			idx=-1;
			break;
		}
		c=tmp[i];
	}
	return idx;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		int flag=0,gx=0;
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			b[i]=a[i];
			if(i>1)
			{
				if(gx==1&&a[i]<a[i-1]) flag=i;
				if(gx==2&&a[i]>a[i-1]) flag=i;
				if(!flag&&a[i]>a[i-1]) gx=1;
				if(!flag&&a[i]<a[i-1]) gx=2;
			}
		}
		reverse(b+1,b+1+n);
		/*
		转
		反
		反转
		转反
		反转反		
		*/
		if(flag)//非单调,仅仅反肯定不行了
		{
			//三种操作,取最小值或者输出-1
			int v1=z(),v2=zf(),v3=fzf(),v4=fz();
			if(v1!=-1||v2!=-1||v3!=-1) 
			{
				if(v1==-1) v1=0x3f3f3f3f;
				if(v2==-1) v2=0x3f3f3f3f;
				if(v3==-1) v3=0x3f3f3f3f;
				if(v4==-1) v4=0x3f3f3f3f;
				int ans=min(v1,v2);
				ans=min(v3,ans);
				ans =min(v4,ans);
				printf("%d\n",ans);
			}
			else printf("-1\n");
		}
		else
		{
			if(gx<=1) printf("0\n");
			else printf("1\n");
		}
	}
}

反思:要通过这次的D记住有时候单点不能确定的时候,要考虑能不能确定点所在的区间,通过F要记住凡是讨论一定要把所有情况都讨论完整。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

构建一个语音转文字的WebApi服务

构建一个语音转文字的WebApi服务 简介 由于业务需要&#xff0c;我们需要提供一个语音输入功能&#xff0c;以便更方便用户的使用&#xff0c;所以我们需要提供语音转文本的功能&#xff0c;下面我们将讲解使用Whisper将语音转换文本&#xff0c;并且封装成WebApi提供web服务…

【WebSocket】使用ws搭建一个简单的在线聊天室

前言 什么是WebSockets&#xff1f; WebSockets 是一种先进的技术。它可以在用户的浏览器和服务器之间打开交互式通信会话。使用此 API&#xff0c;你可以向服务器发送消息并接收事件驱动的响应&#xff0c;而无需通过轮询服务器的方式以获得响应。 webscokets 包括webscoket…

AntDesignBlazor示例——创建列表页

本示例是AntDesign Blazor的入门示例&#xff0c;在学习的同时分享出来&#xff0c;以供新手参考。 示例代码仓库&#xff1a;https://gitee.com/known/AntDesignDemo 1. 学习目标 使用Table组件创建列表页面使用DisplayName特性显示中文表头使用模板和Tag组件显示高温数据使…

2023站酷CUBE设计大会,以AIGC赋能创意人

12月6日&#xff0c;2023站酷CUBE设计大会在厦门举行。大会以“AI与热爱”为主题&#xff0c;由美图与站酷联合举办&#xff0c;邀请了多位创意先锋进行分享&#xff0c;旨在构建设计新生态&#xff0c;以AIGC内容生产新范式为创意人持续赋能&#xff0c;共同提升设计价值。 美…

简单自定义vuex的设计思路

vuex集中式存储管理应用所有组件的状态&#xff0c;并以响应的规则保证状态以可预测的方式 发生变化。 步骤&#xff1a; 1.Store类&#xff0c;保存选项&#xff0c;_mutations&#xff0c;_actions&#xff0c;getters 2.响应式状态&#xff1a;new Vue方式设置响应式。 …

电脑开机提示“未正确启动”怎么办?

有时我们在打开电脑时&#xff0c;会出现蓝屏&#xff0c;并提示“电脑未正确启动”&#xff0c;那么&#xff0c;这该怎么办呢&#xff1f;下面我们就来了解一下。 方法一&#xff1a;执行系统还原 我们在上文中提到了Windows无法正确启动的问题可能是由于三方程序或者近期的…

Java利用TCP实现简单的双人聊天

一、创建新项目 首先创建一个新的项目&#xff0c;并命名为聊天。然后创建包&#xff0c;创建两个类&#xff0c;客户端&#xff08;SocketClient&#xff09;和服务器端&#xff08;SocketServer&#xff09; 二、实现代码 客户端代码&#xff1a; package 聊天; import ja…

Spring Boot 3.2项目中使用缓存Cache的正确姿势!!!

你是否曾想过为什么在 Spring Boot 应用中缓存是如此重要&#xff1f;答案在于它通过减少数据检索时间来提高性能。在本文中&#xff0c;我们将深入探讨缓存对微服务模式的影响&#xff0c;并探讨根据操作易用性、速度、可用性和可观测性等因素选择正确缓存的重要性。我们还将探…

[RISCV] 发现一个可以看RISC-V CPU行为的开源项目

最近在浏览某大型程序员交友 网站的时候发现一个好玩的项目,介绍如下: A small program that handles mie, msi, mti and trap interrupts and updates some global variables on interrupts. 重点是他下面还放了一张图: 能看到RISCV CSR的行为太酷啦!!! 下面一起setup一…

Sourcepawn脚本入门(二)命令与事件监听

&#x1f34e;Sourcepawn脚本入门(二)命令与事件监听 &#xff08;控制台&#xff09;命令是常用的插件形式&#xff0c;eg. noclip …等都是常用的命令&#xff0c;在游戏中使用也很容易,souremod可以注册自己的命令。 事件的监听则需要考虑到不同的起源游戏支持的事件不同&am…

中文BERT模型预训练参数总结以及转化为pytorch的方法

1.目前针对中文的bert预训练模型有三家&#xff1a; 谷歌发布的chinese_L-12_H-768_A-12 还有哈工大的chinese-bert-wwm / chinese-bert-wwm-ext 以及HuggingFace上的bert-base-chinese(由清华大学基于谷歌的BERT在中文数据集上训练开发的模型&#xff0c;上传在HuggingFace) …

彻底删除VsCode配置和安装过的插件与缓存

前言 当你准备对 Visual Studio Code&#xff08;VSCode&#xff09;进行重新安装时&#xff0c;可能遇到一个常见问题&#xff1a;重新安装后&#xff0c;新的安装似乎仍然保留了旧的配置信息&#xff0c;这可能会导致一些麻烦。这种情况通常是由于卸载不彻底所致&#xff0c…

【LVS实战】04 LVS+Keepalived实现负载均衡高可用

一、介绍 Keepalived 是一个用于 Linux 平台的高可用性软件。它实现了虚拟路由器冗余协议 (VRRP) 和健康检查功能&#xff0c;可以用于确保在多台服务器之间提供服务的高可用性。Keepalived 可以检测服务器的故障&#xff0c;并在主服务器宕机时&#xff0c;自动将备份服务器提…

外卖系统源码开发:打造高效智能化餐饮解决方案

在当今数字化时代&#xff0c;外卖系统成为了餐饮业中不可或缺的一部分。为了满足日益增长的外卖需求&#xff0c;我们将深入探讨外卖系统源码开发的关键技术和创新应用。 1. 技术栈选择 在开始外卖系统源码的开发之前&#xff0c;我们首先需要选择适用的技术栈。一个典型的…

【langchain实战】开源项目-RasaGPT

1、概述 RasaGpt是一个建立在 Rasa 和 Langchain 之上的没有显示界面的LMM聊天机器人平台。它是一个Rasa和Telegram这种利用像Langchain这样的LMM库进行索引、检索和上下文注入的样板及参考实现。 开源地址&#xff1a; GitHub - paulpierre/RasaGPT: &#x1f4ac; RasaGPT is…

揭秘:软件测试中Web请求的完整流程!

在软件开发的过程中&#xff0c;测试是一个至关重要的环节。而在现代互联网应用中&#xff0c;Web请求是很常见的一个测试需求。本文将介绍Web请求的完整测试流程&#xff0c;帮助读者更好地理解软件测试的关键步骤。 一、测试准备阶段 在进行Web请求测试之前&#xff0c;测试团…

【CMake入门】第二节——CMake常用指令介绍

系列文章&#xff1a; 【CMake入门】第一节——CMake的安装与简单样例 CMake常用指令介绍 cmake_minimum_required 指定要求最小的cmake版本&#xff0c;如果版本小于该要求&#xff0c;程序终止 project(test) 设置当前项目名称为test CMAKE_BUILD_TYPE 用于设置CMake构…

招商银行薪福:一站式API连接电商平台,实现CRM与客服系统集成

招商银行薪福通的API集成优势 招商银行的SaaS产品薪福通在电商行业迅速崭露头角&#xff0c;它通过一站式API连接&#xff0c;极大地简化了电商平台与CRM及客服系统的集成过程。企业无需深入研究API开发细节&#xff0c;也不必担心代码复杂性&#xff0c;就能实现系统间的高效…

LeetCode力扣每日一题(Java):14、最长公共前缀

一、题目 二、解题思路 1、我的思路 乍一看我的代码量还是比较少&#xff0c;但是提交上去发现时间效率和空间效率都不占优势 讲讲我的思路&#xff1a;首先通过for循环找出数组中长度最短的字符串&#xff0c;并用min储存最短字符串的长度&#xff0c;最长公共前缀不可能比…

SAP MM 中的业务伙伴确定配置

这篇博客文章将概述 SAP MM 供应商帐户组中的合作伙伴确定是什么以及如何在 S/4 系统中配置它。 本文将指导您完成分步过程&#xff0c;并为您提供有关在供应商主数据中使用合作伙伴确定的完整想法。 合作伙伴角色 供应商在 SAP 中扮演着不同类型的角色&#xff0c;让我们通…