EPIC Institute of Technology Round August 2024 (Div. 1 + Div. 2)

news2024/11/16 3:22:08

前言

        又是一场压线不掉分的比赛。

        Standings:2706

        题目链接:Dashboard - EPIC Institute of Technology Round August 2024 (Div. 1 + Div. 2) - Codeforces

A. Distanced Coloring

        题意:

        给一个 n * m 的矩阵,涂色,要求任意两个相同颜色的块,他们横纵坐标差值的最大值不超过 k ,问涂色至少需要几种颜色。

        思路:

        很显然要让每种颜色的格子呈现一种最紧凑的排列方式,于是每隔 k 个位置放一样的颜色。

#include<cstdio>
#include<cstring>
using namespace std;

int T,n,m,k;

int min(int x,int y) { return x < y ? x : y ; }

int main()
{
	scanf("%d",&T);
	while (T --)
	{
		scanf("%d%d%d",&n,&m,&k);
		if(n < m)
		{
			int tmp = n;
			n = m;
			m = tmp;
		}
		int x = min(n,k);
		printf("%d\n",x * min(k,m));
	}
	return 0;
}

B. Removals Game

        题意:

        给两个序列 a 和 b ,Alice 和 Bob 依次取走一个数,只能取两端的数,若两个人最后剩下的那个数相等则 Bob 获胜,反之 Alice 获胜。

        思路:

        容易发现 Bob 必须要 “跟着 Alice 取” 才能获胜,手模一下可以发现 a 和 b 必须是一致的或者互为逆序列才能让 Bob 获胜,否则 Alice 必胜。

        (比赛时代码打得有点丑)

#include<cstdio>
#include<cstring>
using namespace std;

#define N 300005

int T,n,a[N],b[N];

int main()
{
	scanf("%d",&T);
	while (T --)
	{
		scanf("%d",&n);
		for (int i = 1;i <= n;++ i) scanf("%d",&a[i]);
		for (int i = 1;i <= n;++ i) scanf("%d",&b[i]);
		int la,ra,lb,rb,flag;
		la = lb = 1,ra = rb = n,flag = 0;
		while (la <= ra)
		{
			if((a[la] != b[lb] && a[la] != b[rb]) || (a[ra] != b[lb] && a[ra] != b[rb]))
			{
				flag = 1;
				break;
			}
			if(a[la] == b[lb]) ++ la,++ lb;
			else ++ la,-- rb;
		}
		if(flag) printf("Alice\n");
		else printf("Bob\n");
	}
	return 0;
}

C. Black Circles

        题意:

        给你一些圆心,一个起点和一个终点,这些圆初始的半径是零,半径随时间均匀增加,你需要从起点走到终点,速度和半径增加的速率相同,判断走到终点的过程中会不会碰到圆。

        思路:

        显然要走直线,只需判断当人走到终点时有没有圆已经扩散到终点即可。

        因为如果人和圆在终点前的某处会相交,那说明人到终点的时候圆一定也到了,因此我们只需判断终点处即可。

      (比赛时看错了一个样例数据然后对题目各种猜想并百思不能其解浪费了很多时间。。。)

#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;

#define N 100005

int T,n;
long long x[N],y[N],xs,ys,xt,yt,dis;

long long count(long long x1,long long y1,long long x2,long long y2)
{
	return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
}

int main()
{
	scanf("%d",&T);
	while (T --)
	{
		scanf("%d",&n);
		for (int i = 1;i <= n;++ i) scanf("%lld%lld",&x[i],&y[i]);
		scanf("%lld%lld%lld%lld",&xs,&ys,&xt,&yt);
		dis = count(xs,ys,xt,yt);
		int flag = 1;
		for (int i = 1;i <= n;++ i)
		{
			long long now = count(x[i],y[i],xt,yt);
			if(now <= dis)
			{
				flag = 0;
				break;
			}
		}
		if(flag) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}

D1. DFS Checker (Easy Version)

        题意:

        给一棵从 1 ~ n 标号的满二叉树和一个长度为 n 的排列 p,每次询问交换 p 中的两个值,判断能否使得到的新序列成为这课满二叉树的一种 dfs 序。其中询问的交换操作是持久化的,

        思路:

        思考一下满二叉树的特性:所有非叶子节点 k 有且仅有 2 个儿子,且儿子的编号分别为 k + 1 和 k + son[k] + 1 (这里 son[k] 表示 k 的左边或右边子树的大小)。

        想到这其实问题就迎刃而解了。我们暴力的想法就是扫一遍 p 数组,判断每一位 k 的儿子是否在合法的位置( k + 1 或 k + son[k] + 1 )上即可。这里询问只会改变两个数 x 和 y ,而对每个位置是否合法产生的影响只有 x ,y 及其前后的位置,因此我们可以做如下优化:统计当前 p 数组内合法的位置,每次询问更改对应位置上的 bool 值以及当前合法的位置总数,若某次操作后得到全部位置都合法,那就说明这是一个符合条件的 dfn 。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define N 500005

int T,n,q,p[N],f[N],id[N],son[N],now;

void change(int k,int w)
{
	if(w)
	{
		if(!f[k]) f[k] = 1,++ now;
	}
	else
	{
		if(f[k]) f[k] = 0,-- now;
	}
	return;
}

void check(int k)
{
	int x,y;
	int bz = 0;
	if(k >= (n + 1) / 2) bz = 1;
	else
	{
		x = k * 2,y = k * 2 + 1;
		if(id[k] + son[k] + 1 <= n)
		{
			if(p[id[k] + 1] == x && p[id[k] + son[k] + 1] == y)
			{
				if(f[x] && f[y]) bz = 1;
			}
			if(p[id[k] + 1] == y && p[id[k] + son[k] + 1] == x)
			{
				if(f[x] && f[y]) bz = 1;
			}
		}
	}
	change(k,bz);
	return;
}

int main()
{
	scanf("%d",&T);
	while (T --)
	{
		scanf("%d%d",&n,&q);
		for (int i = 1,x;i < n;++ i) scanf("%d",&x);
		for (int i = 1;i <= n;++ i) scanf("%d",&p[i]),id[p[i]] = i,f[i] = 0;
		for (int i = n; i ;-- i)
		{
			if(i >= (n + 1) / 2) son[i] = 0;
			else son[i] = son[i * 2] * 2 + 1;
		}
		for (int i = n,x,y; i ;-- i)
		{
			if(i >= (n + 1) / 2) f[i] = 1;
			else
			{
				x = i * 2,y = i * 2 + 1;
				if(id[i] + son[i] + 1 > n) continue;
				if(p[id[i] + 1] == x && p[id[i] + son[i] + 1] == y)
				{
					if(f[x] && f[y]) f[i] = 1;
				}
				if(p[id[i] + 1] == y && p[id[i] + son[i] + 1] == x)
				{
					if(f[x] && f[y]) f[i] = 1;
				}
			}
		}
		now = 0;
		for (int i = 1;i <= n;++ i) now += (f[i]);
		while (q --)
		{
			int x,y,tmp;
			scanf("%d%d",&x,&y);
			tmp = p[x],p[x] = p[y],p[y] = tmp;
			x = p[x],y = p[y];
			tmp = id[x],id[x] = id[y],id[y] = tmp;
			while (x && y)
			{
				if(x > y) check(x),x >>= 1;
				else if(x < y) check(y),y >>= 1;
				else check(y),check(x),x >>= 1,y >>= 1;
			}
			if(now == n) printf("YES\n");
			else printf("NO\n");
		}
	}
	return 0;
}

D2. DFS Checker (Hard Version)

        题意:

        和 Easy Version 的区别:给的不是一棵满二叉树,而是更普遍的任意树。

        思路:

        这样一来每个节点的儿子数目就不确定了,若某个节点的孩子很多,询问又总是包含这个节点,那么势必会超时,我们需要考虑更普适的方法。

        从 p 数组入手,思考一下合法的 dfn 数组每个位置上的点和前后位置上的点有什么关系:结论是 “要么前一个点是后一个点的父亲,要么前一个点是叶子节点并且这两个点的 lca 是后一个点的父亲” 。这个结论容易理解,是合法的 dfn 数组的必要条件,关键是这个结论是否是充分条件。

        当然是。倘若数组 p 的每个位置都符合上述条件,那么我们从叶子节点往上思考,每一层都一定是合法的,这样整棵树也必然是可以构造出来的。

        因此我们还是按照类似 Easy Version 的做法,统计当前 p 数组里有多少个合法位置,每次询问操作进行修改即可。

#include<cstdio>
#include<cstring>
using namespace std;

#define N 300005

int T,n,q,f[N][22],st[N],dep[N],p[N],leaf[N],bz[N],lg[N],cnt,now;

struct Edge
{
	int next,to;
}ed[N << 1];

void add(int u,int v)
{
	ed[++ cnt].next = st[u];
	ed[cnt].to = v;
	st[u] = cnt;
	return;
}

void dfs(int x,int fa)
{
	dep[x] = dep[fa] + 1;
	for (int i = 1;(1 << i) <= dep[x];++ i)
		f[x][i] = f[f[x][i - 1]][i - 1];
	int flag = 1;
	for (int i = st[x]; ~i ;i = ed[i].next)
		if(ed[i].to != fa)
		{
			dfs(ed[i].to,x);
			flag = 0;
		}
	leaf[x] = flag;
	return;
}

int lca(int x,int y)
{
	if(dep[x] < dep[y])
	{
		int tmp = x;
		x = y,y = tmp;
	}
	while (dep[x] > dep[y]) x = f[x][lg[dep[x] - dep[y]]];
	if(x == y) return x;
	for (int i = lg[dep[x]];i >= 0;-- i)
		if(f[x][i] != f[y][i])
			x = f[x][i],y = f[y][i];
	return f[x][0];
}

int check(int x)
{
	int f1,f2;
	f1 = f2 = 0;
	if(x > 1)
	{
		if(p[x - 1] == f[p[x]][0]) f1 = 1;
		else if(lca(p[x - 1],p[x]) == f[p[x]][0] && leaf[p[x - 1]]) f1 = 1;
	}
	else f1 = 1;
	if(x < n)
	{
		if(p[x] == f[p[x + 1]][0]) f2 = 1;
		else if(lca(p[x],p[x + 1]) == f[p[x + 1]][0] && leaf[p[x]]) f2 = 1;
	}
	else f2 = 1;
	return (f1 & f2) ;
}

void change(int k,int w)
{
	if(k < 1 || k > n) return;
	if(!bz[k] && w) bz[k] = 1,++ now;
	else if(bz[k] && !w) bz[k] = 0,-- now;
	return;
}

int main()
{
	lg[1] = 0;
	for (int i = 2;i <= 300000;++ i) lg[i] = lg[i >> 1] + 1;
	scanf("%d",&T);
	while (T --)
	{
		scanf("%d%d",&n,&q),st[1] = -1,dep[0] = f[1][0] = cnt = now = 0;
		for (int i = 2;i <= n;++ i) scanf("%d",&f[i][0]),add(i,f[i][0]),add(f[i][0],i),st[i] = -1;
		dfs(1,0);
		for (int i = 1;i <= n;++ i) scanf("%d",&p[i]);
		for (int i = 1;i <= n;++ i) bz[i] = check(i),now += bz[i];
		while (q --)
		{
			int x,y,tmp;
			scanf("%d%d",&x,&y);
			tmp = p[x],p[x] = p[y],p[y] = tmp;
			change(x,0),change(x - 1,0),change(x + 1,0);
			change(y,0),change(y - 1,0),change(y + 1,0);
			change(x,check(x)),change(y,check(y));
			if(x > 1) change(x - 1,check(x - 1));
			if(x < n) change(x + 1,check(x + 1));
			if(y > 1) change(y - 1,check(y - 1));
			if(y < n) change(y + 1,check(y + 1));
			if(now == n) printf("YES\n");
			else printf("NO\n");
		}
	}
	return 0;
}

E. Cosmic Rays

        题意:

        给一个序列 s ,每秒钟宇宙射线都会辐射这个序列,使得所有 s_i \neq s_{i - 1} 的 s_i 消失。序列 s 以 (a,b)对的形式给出,表示每个 b 有 a 个,对于所有的 i = 1,2,...,n ,计算前 i 组数形成的序列 s 变成空序列花费的时间。

        思路:

        一眼单调栈,维护每组数前面的 “佼佼者” ,即到这组数之前能最后剩下的那组数。

        若当前这组数可以直接或者通过跨越与前面的数合并,那么更新当前的佼佼者。

        若当前这组数的个数没有前面的多,那意味着无法跨越到前面去合并。

        单调栈维护即可。

#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;

#define N 300005

int T,n;
long long a[N],b[N],ans;

stack<long long> st;

long long max(long long x,long long y) { return x > y ? x : y ; }

int main()
{
	int num = 0;
	scanf("%d",&T);
	while (T --)
	{
		scanf("%d",&n),ans = 0ll;
		for (int i = 1;i <= n;++ i) scanf("%lld%lld",&a[i],&b[i]);
		while (!st.empty()) st.pop();
		for (int i = 1;i <= n;++ i)
		{
			long long now = 0ll;
			while (!st.empty() && ((b[st.top()] != b[i] && a[i] >= a[st.top()]) || (b[st.top()] == b[i])))
			{
				if(b[st.top()] != b[i]) now = max(now,a[st.top()]);
				else
				{
					int las = st.top();
					a[i] = a[i] + a[las] - now;
				}
				st.pop();
			}
			st.push(i);
			ans = max(ans,a[i]);
			++ num;
			printf("%lld ",ans);
		}
		printf("\n");
	}
	return 0;
}

总结

        貌似还是前面的题目太容易卡了,div 2 后面的 EF 题很多时候都是可做的但是没有时间,甚至有时候 D 都没开出来,可能需要多练练 B 这种小巧玲珑的思维题。

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

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

相关文章

pkg 打包后运行报错 Cannot mkdir in a snapshot. Try mountpoints instead.

把项目中使用到的 __dirname 类似这样的 join(__dirname, ./config)替换为 process.cwd() __dirname&#xff1a;获取的是当前文件目录路径&#xff0c;二进制文件内部的文件(pkg打包的二进制文件是快照文件&#xff0c;里面的文件只能读不能修改新增)&#xff0c;比如&#x…

区块链基础

1、区块链定义 区块链技术本质上是一个去中心化的数据库&#xff0c;它是比特币的核心技术与基础架构&#xff0c;是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。狭义来讲&#xff0c;区块链是一种按照时间顺序将数据区块以顺序相连的方式组合…

XSS-跨站脚本攻击

目录 XSS简介 XSS分类 反射型XSS&#xff08;非持久型XSS&#xff09; 存储型XSS&#xff08;持久型XSS&#xff09; DOM型XSS HTML文档解析过程 例题 HTML解析 字符实体(character entities) HTML字符实体(HTML character entities) 字符引用&#xff08;character…

程序员如何写PLC程序

PLC是可编程逻辑控制器的简称&#xff0c;常用的编程语言是IEC61131-3&#xff08;梯形图、结构化文本、指令表、功能块、顺序功能图&#xff09;和西门子的SCL。程序员常用的编程语言是JS、Java、Python、C/C、Go等。PLC广泛采用编程工具有codesys、博图等。程序员常用的编程工…

用Python实现9大回归算法详解——06. K近邻回归算法

1. K近邻回归的基本概念 K近邻回归&#xff08;K-Nearest Neighbors Regression, KNN Regression&#xff09;是一种基于实例的学习方法。与传统的回归模型不同&#xff0c;KNN回归不通过显式的函数来建模数据之间的关系&#xff0c;而是通过查找输入样本的“邻居”来进行预测…

【PDF技巧】如何编辑忘记密码PDF文件?

PDF文件打开之后&#xff0c;发现编辑功能都是灰色的&#xff0c;无法使用&#xff0c;无法编辑PDF文件&#xff0c;遇到这种情况&#xff0c;因为PDF文件设置了限制编辑导致的。一般情况下&#xff0c;我们只需要输入PDF密码&#xff0c;将限制编辑取消就可以正常编辑文件了&a…

在线装修管理系统pf

TOC springboot389在线装修管理系统pf 第1章 绪论 1.1 课题背景 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。所以各行业…

C语言 | Leetcode C语言题解之第345题反转字符串中的元音字母

题目&#xff1a; 题解&#xff1a; char vowel[] "aeiouAEIOU";bool isVowel(char ch) {for (int i 0; vowel[i]; i) {if (vowel[i] ch) {return true;}}return false; };char* reverseVowels(char* s) {int n strlen(s);int i 0, j n - 1;while (i < j) …

C语言三目运算符深度解析

[大师C语言]合集&#xff3b;大师C语言(第一篇)&#xff3d;C语言栈溢出背后的秘密&#xff3b;大师C语言(第二十五篇)&#xff3d;C语言字符串探秘&#xff3b;大师C语言(第二篇)&#xff3d;C语言main函数背后的秘密&#xff3b;大师C语言(第二十六篇)&#xff3d;C语言结构体…

08 STM32 DMA

DMA 协助CPU&#xff0c;完成数据转运工作。 两个程序&#xff1a; DMA数据转运&#xff0c;DMAAD多通道 DMA数据转运&#xff0c;将使用DMA&#xff0c;进行存储器到存储器的数据转运&#xff0c;也就是把一个数组里面的数据&#xff0c;复制到另一个数组里。 定义一个数组D…

3:html(CSS):基础语法3

3.1网页布局与id 3.1.1网页布局 在这里将使用<div>分成一个一个的块&#xff0c;然后进行CSS的美化。这里要说一下html是一个前端的代码&#xff0c;但是它写出来的东西单调缺少美感&#xff0c;CSS就是进行美化的&#xff0c;这里我们使用类的概念来美化我们的网站。 …

apt E: 无法定位软件包 winehq-stable

执行了 添加wine源 wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/jammy/winehq-jammy.sources还需要执行 更新源 apt update

【观察】星河AI网络:构筑AI时代高质量网络底座,撑起新质生产力发展的浩瀚星空...

知名科技杂志《连线》创始主编凯文凯利曾预测&#xff1a;“在未来的 100 年里&#xff0c;人工智能将超越任何一种人工力量&#xff0c;将人类引领到一个前所未有的时代。” 确实如此&#xff0c;犹如历史上蒸汽机、电力、计算机和互联网等通用技术一样&#xff0c;近20年来&a…

【邀请函】2024 PowerData数字经济-开源行:NineData联合主办,并探讨面向Doris实时数据仓库的应用

2024年8月25日&#xff0c;PowerData 技术社区以“数字经济-城市开源行”为主题技术沙龙将在杭州 NineData 公司举办。本次活动由 SelectDB、NineData、字节跳动ByConity、阿里云 Flink CDC 等联合主办&#xff0c;围绕技术应用&#xff0c;最佳实践、迁移同步、以及数据管理等…

NoSQL之Redis配置与优化(二)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

live2d + edge-tts 优雅的实现数字人讲话 ~

震惊&#xff01;live2d数字人竟开口说话 ~ 之前有想做数字人相关项目&#xff0c;查了一些方案。看了一些三方大厂的商用方案&#xff0c;口型有点尴尬&#xff0c;而且很多是采用视频流的方案&#xff0c;对流量的消耗很大。后来了解了live2d 技术&#xff0c;常在博客网页上…

【Go语言初探】(三)、运行程序报错:Cannot find package “xxx“

一、问题描述 在运行项目中的main.go文件时&#xff0c;报错&#xff1a;Error: Cannot find package cast 报错截图如下&#xff1a; 二、原因及解决方法 出现上述报错的原因是&#xff0c;运行方法栏中选择了“Package”&#xff08;包运行&#xff09;&#xff0c;改成“…

WebGoC题解(19) 12569.(2022GoC能力测试第5题)智慧树 难度:4

时限&#xff1a;5s 空间&#xff1a;256m 通过次数&#xff1a;827 题目描述 有一种智慧树&#xff0c;它是这样生长的&#xff0c;它先长出长度50的主干&#xff0c;才开始长侧枝&#xff0c;每长出一根侧枝&#xff0c;主干就向上长出长度30。如果侧枝长度是偶数&am…

了解 K-Means 聚类的工作原理(详细指南)

一、说明 K-means 的目标是将一组观测值划分为 k 个聚类&#xff0c;每个观测值分配给均值&#xff08;聚类中心或质心&#xff09;最接近的聚类&#xff0c;从而充当该聚类的代表。 在本文中&#xff0c;我们将全面介绍 k 均值聚类&#xff08;最常用的聚类方法之一&#xff0…

Python 全栈系列263 简易资源监控

说明 开始比等待强 这块其实我也不太熟&#xff0c;而且我也知道应该有更专业的做法 其实连grafana我都准备好了&#xff0c;prometheus的镜像也准备好了&#xff0c;但是还没时间去细细弄。 我想先快快整一版够用的&#xff08;能让我依据这个数据进行调度&#xff09;就行。…